diff --git a/github/MainClass.py b/github/MainClass.py
index 57d329e9..2cc9f240 100644
--- a/github/MainClass.py
+++ b/github/MainClass.py
@@ -47,38 +47,59 @@
# along with PyGithub. If not, see . #
# #
################################################################################
+from __future__ import annotations
import pickle
import warnings
from datetime import datetime
-from typing import List
+from typing import TYPE_CHECKING, Any, BinaryIO, TypeVar
import urllib3
+from urllib3.util import Retry
import github.ApplicationOAuth
+import github.Auth
+import github.AuthenticatedUser
import github.Enterprise
import github.Event
import github.Gist
-import github.GithubObject
+import github.GithubApp
+import github.GithubIntegration
+import github.GithubRetry
+import github.GitignoreTemplate
import github.License
import github.NamedUser
-import github.PaginatedList
import github.Topic
-from github import Auth
+from github import Consts
+from github.GithubIntegration import GithubIntegration
+from github.GithubObject import GithubObject, NotSet, Opt, is_defined
+from github.GithubRetry import GithubRetry
+from github.HookDelivery import HookDelivery, HookDeliverySummary
+from github.HookDescription import HookDescription
+from github.PaginatedList import PaginatedList
+from github.RateLimit import RateLimit
+from github.Requester import Requester
-from . import (
- AuthenticatedUser,
- Consts,
- GithubApp,
- GithubRetry,
- GitignoreTemplate,
- HookDelivery,
- HookDescription,
- RateLimit,
- Repository,
-)
-from .HookDelivery import HookDeliverySummary
-from .Requester import Requester
+if TYPE_CHECKING:
+ from github.AppAuthentication import AppAuthentication
+ from github.ApplicationOAuth import ApplicationOAuth
+ from github.AuthenticatedUser import AuthenticatedUser
+ from github.Commit import Commit
+ from github.ContentFile import ContentFile
+ from github.Event import Event
+ from github.Gist import Gist
+ from github.GithubApp import GithubApp
+ from github.GitignoreTemplate import GitignoreTemplate
+ from github.Issue import Issue
+ from github.License import License
+ from github.NamedUser import NamedUser
+ from github.Organization import Organization
+ from github.Project import Project
+ from github.ProjectColumn import ProjectColumn
+ from github.Repository import Repository
+ from github.Topic import Topic
+
+TGithubObject = TypeVar("TGithubObject", bound=GithubObject)
class Github:
@@ -86,7 +107,9 @@ class Github:
This is the main class you instantiate to access the Github API v3. Optional parameters allow different authentication methods.
"""
- default_retry = GithubRetry.GithubRetry()
+ __requester: Requester
+
+ default_retry = GithubRetry()
# keep non-deprecated arguments in-sync with Requester
# v3: remove login_or_token, password, jwt and app_auth
@@ -95,21 +118,21 @@ class Github:
# allows to reorder / add new arguments / remove deprecated arguments without breaking user code
def __init__(
self,
- login_or_token=None,
- password=None,
- jwt=None,
- app_auth=None,
- base_url=Consts.DEFAULT_BASE_URL,
- timeout=Consts.DEFAULT_TIMEOUT,
- user_agent=Consts.DEFAULT_USER_AGENT,
- per_page=Consts.DEFAULT_PER_PAGE,
- verify=True,
- retry=default_retry,
- pool_size=None,
- seconds_between_requests=Consts.DEFAULT_SECONDS_BETWEEN_REQUESTS,
- seconds_between_writes=Consts.DEFAULT_SECONDS_BETWEEN_WRITES,
- auth=None,
- ):
+ login_or_token: str | None = None,
+ password: str | None = None,
+ jwt: str | None = None,
+ app_auth: AppAuthentication | None = None,
+ base_url: str = Consts.DEFAULT_BASE_URL,
+ timeout: int = Consts.DEFAULT_TIMEOUT,
+ user_agent: str = Consts.DEFAULT_USER_AGENT,
+ per_page: int = Consts.DEFAULT_PER_PAGE,
+ verify: bool | str = True,
+ retry: int | Retry | None = default_retry,
+ pool_size: int | None = None,
+ seconds_between_requests: float | None = Consts.DEFAULT_SECONDS_BETWEEN_REQUESTS,
+ seconds_between_writes: float | None = Consts.DEFAULT_SECONDS_BETWEEN_WRITES,
+ auth: github.Auth.Auth | None = None,
+ ) -> None:
"""
:param login_or_token: string deprecated, use auth=github.Auth.Login(...) or auth=github.Auth.Token(...) instead
:param password: string deprecated, use auth=github.Auth.Login(...) instead
@@ -141,7 +164,7 @@ class Github:
assert pool_size is None or isinstance(pool_size, int), pool_size
assert seconds_between_requests is None or seconds_between_requests >= 0
assert seconds_between_writes is None or seconds_between_writes >= 0
- assert auth is None or isinstance(auth, Auth.Auth), auth
+ assert auth is None or isinstance(auth, github.Auth.Auth), auth
if password is not None:
warnings.warn(
@@ -149,13 +172,13 @@ class Github:
"auth=github.Auth.Login(...) instead",
category=DeprecationWarning,
)
- auth = Auth.Login(login_or_token, password)
+ auth = github.Auth.Login(login_or_token, password) # type: ignore
elif login_or_token is not None:
warnings.warn(
"Argument login_or_token is deprecated, please use " "auth=github.Auth.Token(...) instead",
category=DeprecationWarning,
)
- auth = Auth.Token(login_or_token)
+ auth = github.Auth.Token(login_or_token)
elif jwt is not None:
warnings.warn(
"Argument jwt is deprecated, please use "
@@ -163,7 +186,7 @@ class Github:
"auth=github.Auth.AppAuthToken(...) instead",
category=DeprecationWarning,
)
- auth = Auth.AppAuthToken(jwt)
+ auth = github.Auth.AppAuthToken(jwt)
elif app_auth is not None:
warnings.warn(
"Argument app_auth is deprecated, please use " "auth=github.Auth.AppInstallationAuth(...) instead",
@@ -195,44 +218,36 @@ class Github:
"""
self.__requester.close()
- def __enter__(self) -> "Github":
+ def __enter__(self) -> Github:
return self
- def __exit__(self, exc_type, exc_val, exc_tb) -> None:
+ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
self.close()
@property
- def FIX_REPO_GET_GIT_REF(self):
- """
- :type: bool
- """
+ def FIX_REPO_GET_GIT_REF(self) -> bool:
return self.__requester.FIX_REPO_GET_GIT_REF
@FIX_REPO_GET_GIT_REF.setter
- def FIX_REPO_GET_GIT_REF(self, value):
+ def FIX_REPO_GET_GIT_REF(self, value: bool) -> None:
self.__requester.FIX_REPO_GET_GIT_REF = value
# v3: Remove this property? Why should it be necessary to read/modify it after construction
@property
- def per_page(self):
- """
- :type: int
- """
+ def per_page(self) -> int:
return self.__requester.per_page
@per_page.setter
- def per_page(self, value):
+ def per_page(self, value: int) -> None:
self.__requester.per_page = value
# v3: Provide a unified way to access values of headers of last response
# v3: (and add/keep ad hoc properties for specific useful headers like rate limiting, oauth scopes, etc.)
# v3: Return an instance of a class: using a tuple did not allow to add a field "resettime"
@property
- def rate_limiting(self):
+ def rate_limiting(self) -> tuple[int, int]:
"""
First value is requests remaining, second value is request limit.
-
- :type: (int, int)
"""
remaining, limit = self.__requester.rate_limiting
if limit < 0:
@@ -240,76 +255,67 @@ class Github:
return self.__requester.rate_limiting
@property
- def rate_limiting_resettime(self):
+ def rate_limiting_resettime(self) -> int:
"""
Unix timestamp indicating when rate limiting will reset.
-
- :type: int
"""
if self.__requester.rate_limiting_resettime == 0:
self.get_rate_limit()
return self.__requester.rate_limiting_resettime
- def get_rate_limit(self):
+ def get_rate_limit(self) -> RateLimit:
"""
Rate limit status for different resources (core/search/graphql).
:calls: `GET /rate_limit `_
- :rtype: :class:`github.RateLimit.RateLimit`
"""
headers, data = self.__requester.requestJsonAndCheck("GET", "/rate_limit")
- return RateLimit.RateLimit(self.__requester, headers, data["resources"], True)
+ return RateLimit(self.__requester, headers, data["resources"], True)
@property
- def oauth_scopes(self):
+ def oauth_scopes(self) -> list[str] | None:
"""
:type: list of string
"""
return self.__requester.oauth_scopes
- def get_license(self, key=github.GithubObject.NotSet):
+ def get_license(self, key: Opt[str] = NotSet) -> License:
"""
:calls: `GET /license/{license} `_
- :param key: string
- :rtype: :class:`github.License.License`
"""
assert isinstance(key, str), key
headers, data = self.__requester.requestJsonAndCheck("GET", f"/licenses/{key}")
return github.License.License(self.__requester, headers, data, completed=True)
- def get_licenses(self):
+ def get_licenses(self) -> PaginatedList[License]:
"""
:calls: `GET /licenses `_
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.License.License`
"""
- url_parameters = dict()
+ url_parameters: dict[str, Any] = {}
- return github.PaginatedList.PaginatedList(github.License.License, self.__requester, "/licenses", url_parameters)
+ return PaginatedList(github.License.License, self.__requester, "/licenses", url_parameters)
- def get_events(self):
+ def get_events(self) -> PaginatedList[Event]:
"""
:calls: `GET /events `_
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Event.Event`
"""
- return github.PaginatedList.PaginatedList(github.Event.Event, self.__requester, "/events", None)
+ return PaginatedList(github.Event.Event, self.__requester, "/events", None)
- def get_user(self, login=github.GithubObject.NotSet):
+ def get_user(self, login: Opt[str] = NotSet) -> NamedUser | AuthenticatedUser:
"""
:calls: `GET /users/{user} `_ or `GET /user `_
- :param login: string
- :rtype: :class:`github.NamedUser.NamedUser` or :class:`github.AuthenticatedUser.AuthenticatedUser`
"""
- assert login is github.GithubObject.NotSet or isinstance(login, str), login
- if login is github.GithubObject.NotSet:
- return AuthenticatedUser.AuthenticatedUser(self.__requester, {}, {"url": "/user"}, completed=False)
+ assert login is NotSet or isinstance(login, str), login
+ if login is NotSet:
+ return github.AuthenticatedUser.AuthenticatedUser(self.__requester, {}, {"url": "/user"}, completed=False)
else:
headers, data = self.__requester.requestJsonAndCheck("GET", f"/users/{login}")
return github.NamedUser.NamedUser(self.__requester, headers, data, completed=True)
- def get_user_by_id(self, user_id):
+ def get_user_by_id(self, user_id: int) -> NamedUser:
"""
:calls: `GET /user/{id} `_
:param user_id: int
@@ -319,48 +325,40 @@ class Github:
headers, data = self.__requester.requestJsonAndCheck("GET", f"/user/{user_id}")
return github.NamedUser.NamedUser(self.__requester, headers, data, completed=True)
- def get_users(self, since=github.GithubObject.NotSet):
+ def get_users(self, since: Opt[int] = NotSet) -> PaginatedList[NamedUser]:
"""
:calls: `GET /users `_
- :param since: integer
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.NamedUser.NamedUser`
"""
- assert since is github.GithubObject.NotSet or isinstance(since, int), since
+ assert since is NotSet or isinstance(since, int), since
url_parameters = dict()
- if since is not github.GithubObject.NotSet:
+ if since is not NotSet:
url_parameters["since"] = since
- return github.PaginatedList.PaginatedList(
- github.NamedUser.NamedUser, self.__requester, "/users", url_parameters
- )
+ return PaginatedList(github.NamedUser.NamedUser, self.__requester, "/users", url_parameters)
- def get_organization(self, login):
+ def get_organization(self, login: str) -> Organization:
"""
:calls: `GET /orgs/{org} `_
- :param login: string
- :rtype: :class:`github.Organization.Organization`
"""
assert isinstance(login, str), login
headers, data = self.__requester.requestJsonAndCheck("GET", f"/orgs/{login}")
return github.Organization.Organization(self.__requester, headers, data, completed=True)
- def get_organizations(self, since=github.GithubObject.NotSet):
+ def get_organizations(self, since: Opt[int] = NotSet) -> PaginatedList[Organization]:
"""
:calls: `GET /organizations `_
- :param since: integer
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Organization.Organization`
"""
- assert since is github.GithubObject.NotSet or isinstance(since, int), since
+ assert since is NotSet or isinstance(since, int), since
url_parameters = dict()
- if since is not github.GithubObject.NotSet:
+ if since is not NotSet:
url_parameters["since"] = since
- return github.PaginatedList.PaginatedList(
+ return PaginatedList(
github.Organization.Organization,
self.__requester,
"/organizations",
url_parameters,
)
- def get_enterprise(self, enterprise):
+ def get_enterprise(self, enterprise: str) -> github.Enterprise.Enterprise:
"""
:calls: `GET /enterprises/{enterprise} `_
:param enterprise: string
@@ -370,58 +368,56 @@ class Github:
# There is no native "/enterprises/{enterprise}" api, so this function is a hub for apis that start with "/enterprise/{enterprise}".
return github.Enterprise.Enterprise(self.__requester, enterprise)
- def get_repo(self, full_name_or_id, lazy=False):
+ def get_repo(self, full_name_or_id: int | str, lazy: bool = False) -> Repository:
"""
:calls: `GET /repos/{owner}/{repo} `_ or `GET /repositories/{id} `_
- :rtype: :class:`github.Repository.Repository`
"""
assert isinstance(full_name_or_id, (str, int)), full_name_or_id
url_base = "/repositories/" if isinstance(full_name_or_id, int) else "/repos/"
url = f"{url_base}{full_name_or_id}"
if lazy:
- return Repository.Repository(self.__requester, {}, {"url": url}, completed=False)
+ return github.Repository.Repository(self.__requester, {}, {"url": url}, completed=False)
headers, data = self.__requester.requestJsonAndCheck("GET", url)
- return Repository.Repository(self.__requester, headers, data, completed=True)
+ return github.Repository.Repository(self.__requester, headers, data, completed=True)
- def get_repos(self, since=github.GithubObject.NotSet, visibility=github.GithubObject.NotSet):
+ def get_repos(
+ self,
+ since: Opt[int] = NotSet,
+ visibility: Opt[str] = NotSet,
+ ) -> PaginatedList[Repository]:
"""
:calls: `GET /repositories `_
:param since: integer
:param visibility: string ('all','public')
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository`
"""
- assert since is github.GithubObject.NotSet or isinstance(since, int), since
- url_parameters = dict()
- if since is not github.GithubObject.NotSet:
+ assert since is NotSet or isinstance(since, int), since
+ url_parameters: dict[str, Any] = {}
+ if since is not NotSet:
url_parameters["since"] = since
- if visibility is not github.GithubObject.NotSet:
+ if visibility is not NotSet:
assert visibility in ("public", "all"), visibility
url_parameters["visibility"] = visibility
- return github.PaginatedList.PaginatedList(
+ return PaginatedList(
github.Repository.Repository,
self.__requester,
"/repositories",
url_parameters,
)
- def get_project(self, id):
+ def get_project(self, id: int) -> Project:
"""
:calls: `GET /projects/{project_id} `_
- :rtype: :class:`github.Project.Project`
- :param id: integer
"""
headers, data = self.__requester.requestJsonAndCheck(
"GET",
- "/projects/%d" % (id),
+ f"/projects/{id:d}",
headers={"Accept": Consts.mediaTypeProjectsPreview},
)
return github.Project.Project(self.__requester, headers, data, completed=True)
- def get_project_column(self, id):
+ def get_project_column(self, id: int) -> ProjectColumn:
"""
:calls: `GET /projects/columns/{column_id} `_
- :rtype: :class:`github.ProjectColumn.ProjectColumn`
- :param id: integer
"""
headers, data = self.__requester.requestJsonAndCheck(
"GET",
@@ -430,49 +426,44 @@ class Github:
)
return github.ProjectColumn.ProjectColumn(self.__requester, headers, data, completed=True)
- def get_gist(self, id):
+ def get_gist(self, id: str) -> Gist:
"""
:calls: `GET /gists/{id} `_
- :param id: string
- :rtype: :class:`github.Gist.Gist`
"""
assert isinstance(id, str), id
headers, data = self.__requester.requestJsonAndCheck("GET", f"/gists/{id}")
return github.Gist.Gist(self.__requester, headers, data, completed=True)
- def get_gists(self, since=github.GithubObject.NotSet):
+ def get_gists(self, since: Opt[datetime] = NotSet) -> PaginatedList[Gist]:
"""
:calls: `GET /gists/public `_
- :param since: datetime format YYYY-MM-DDTHH:MM:SSZ
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Gist.Gist`
"""
- assert since is github.GithubObject.NotSet or isinstance(since, datetime), since
+ assert since is NotSet or isinstance(since, datetime), since
url_parameters = dict()
- if since is not github.GithubObject.NotSet:
+ if is_defined(since):
url_parameters["since"] = since.strftime("%Y-%m-%dT%H:%M:%SZ")
- return github.PaginatedList.PaginatedList(github.Gist.Gist, self.__requester, "/gists/public", url_parameters)
+ return PaginatedList(github.Gist.Gist, self.__requester, "/gists/public", url_parameters)
def search_repositories(
self,
- query,
- sort=github.GithubObject.NotSet,
- order=github.GithubObject.NotSet,
- **qualifiers,
- ):
+ query: str,
+ sort: Opt[str] = NotSet,
+ order: Opt[str] = NotSet,
+ **qualifiers: Any,
+ ) -> PaginatedList[Repository]:
"""
:calls: `GET /search/repositories `_
:param query: string
:param sort: string ('stars', 'forks', 'updated')
:param order: string ('asc', 'desc')
:param qualifiers: keyword dict query qualifiers
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Repository.Repository`
"""
assert isinstance(query, str), query
url_parameters = dict()
- if sort is not github.GithubObject.NotSet: # pragma no branch (Should be covered)
+ if sort is not NotSet: # pragma no branch (Should be covered)
assert sort in ("stars", "forks", "updated"), sort
url_parameters["sort"] = sort
- if order is not github.GithubObject.NotSet: # pragma no branch (Should be covered)
+ if order is not NotSet: # pragma no branch (Should be covered)
assert order in ("asc", "desc"), order
url_parameters["order"] = order
@@ -486,7 +477,7 @@ class Github:
url_parameters["q"] = " ".join(query_chunks)
assert url_parameters["q"], "need at least one qualifier"
- return github.PaginatedList.PaginatedList(
+ return PaginatedList(
github.Repository.Repository,
self.__requester,
"/search/repositories",
@@ -495,25 +486,25 @@ class Github:
def search_users(
self,
- query,
- sort=github.GithubObject.NotSet,
- order=github.GithubObject.NotSet,
- **qualifiers,
- ):
+ query: str,
+ sort: Opt[str] = NotSet,
+ order: Opt[str] = NotSet,
+ **qualifiers: Any,
+ ) -> PaginatedList[NamedUser]:
"""
:calls: `GET /search/users `_
:param query: string
:param sort: string ('followers', 'repositories', 'joined')
:param order: string ('asc', 'desc')
:param qualifiers: keyword dict query qualifiers
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.NamedUser.NamedUser`
+ :rtype: :class:`PaginatedList` of :class:`github.NamedUser.NamedUser`
"""
assert isinstance(query, str), query
url_parameters = dict()
- if sort is not github.GithubObject.NotSet:
+ if sort is not NotSet:
assert sort in ("followers", "repositories", "joined"), sort
url_parameters["sort"] = sort
- if order is not github.GithubObject.NotSet:
+ if order is not NotSet:
assert order in ("asc", "desc"), order
url_parameters["order"] = order
@@ -527,7 +518,7 @@ class Github:
url_parameters["q"] = " ".join(query_chunks)
assert url_parameters["q"], "need at least one qualifier"
- return github.PaginatedList.PaginatedList(
+ return PaginatedList(
github.NamedUser.NamedUser,
self.__requester,
"/search/users",
@@ -536,25 +527,25 @@ class Github:
def search_issues(
self,
- query,
- sort=github.GithubObject.NotSet,
- order=github.GithubObject.NotSet,
- **qualifiers,
- ):
+ query: str,
+ sort: Opt[str] = NotSet,
+ order: Opt[str] = NotSet,
+ **qualifiers: Any,
+ ) -> PaginatedList[Issue]:
"""
:calls: `GET /search/issues `_
:param query: string
:param sort: string ('comments', 'created', 'updated')
:param order: string ('asc', 'desc')
:param qualifiers: keyword dict query qualifiers
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Issue.Issue`
+ :rtype: :class:`PaginatedList` of :class:`github.Issue.Issue`
"""
assert isinstance(query, str), query
url_parameters = dict()
- if sort is not github.GithubObject.NotSet:
+ if sort is not NotSet:
assert sort in ("comments", "created", "updated"), sort
url_parameters["sort"] = sort
- if order is not github.GithubObject.NotSet:
+ if order is not NotSet:
assert order in ("asc", "desc"), order
url_parameters["order"] = order
@@ -568,18 +559,16 @@ class Github:
url_parameters["q"] = " ".join(query_chunks)
assert url_parameters["q"], "need at least one qualifier"
- return github.PaginatedList.PaginatedList(
- github.Issue.Issue, self.__requester, "/search/issues", url_parameters
- )
+ return PaginatedList(github.Issue.Issue, self.__requester, "/search/issues", url_parameters)
def search_code(
self,
- query,
- sort=github.GithubObject.NotSet,
- order=github.GithubObject.NotSet,
- highlight=False,
- **qualifiers,
- ):
+ query: str,
+ sort: Opt[str] = NotSet,
+ order: Opt[str] = NotSet,
+ highlight: bool = False,
+ **qualifiers: Any,
+ ) -> PaginatedList[ContentFile]:
"""
:calls: `GET /search/code `_
:param query: string
@@ -587,14 +576,14 @@ class Github:
:param order: string ('asc', 'desc')
:param highlight: boolean (True, False)
:param qualifiers: keyword dict query qualifiers
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.ContentFile.ContentFile`
+ :rtype: :class:`PaginatedList` of :class:`github.ContentFile.ContentFile`
"""
assert isinstance(query, str), query
url_parameters = dict()
- if sort is not github.GithubObject.NotSet: # pragma no branch (Should be covered)
+ if sort is not NotSet: # pragma no branch (Should be covered)
assert sort in ("indexed",), sort
url_parameters["sort"] = sort
- if order is not github.GithubObject.NotSet: # pragma no branch (Should be covered)
+ if order is not NotSet: # pragma no branch (Should be covered)
assert order in ("asc", "desc"), order
url_parameters["order"] = order
@@ -610,7 +599,7 @@ class Github:
headers = {"Accept": Consts.highLightSearchPreview} if highlight else None
- return github.PaginatedList.PaginatedList(
+ return PaginatedList(
github.ContentFile.ContentFile,
self.__requester,
"/search/code",
@@ -620,25 +609,25 @@ class Github:
def search_commits(
self,
- query,
- sort=github.GithubObject.NotSet,
- order=github.GithubObject.NotSet,
- **qualifiers,
- ):
+ query: str,
+ sort: Opt[str] = NotSet,
+ order: Opt[str] = NotSet,
+ **qualifiers: Any,
+ ) -> PaginatedList[Commit]:
"""
:calls: `GET /search/commits `_
:param query: string
:param sort: string ('author-date', 'committer-date')
:param order: string ('asc', 'desc')
:param qualifiers: keyword dict query qualifiers
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Commit.Commit`
+ :rtype: :class:`PaginatedList` of :class:`github.Commit.Commit`
"""
assert isinstance(query, str), query
url_parameters = dict()
- if sort is not github.GithubObject.NotSet:
+ if sort is not NotSet:
assert sort in ("author-date", "committer-date"), sort
url_parameters["sort"] = sort
- if order is not github.GithubObject.NotSet:
+ if order is not NotSet:
assert order in ("asc", "desc"), order
url_parameters["order"] = order
@@ -652,7 +641,7 @@ class Github:
url_parameters["q"] = " ".join(query_chunks)
assert url_parameters["q"], "need at least one qualifier"
- return github.PaginatedList.PaginatedList(
+ return PaginatedList(
github.Commit.Commit,
self.__requester,
"/search/commits",
@@ -660,12 +649,12 @@ class Github:
headers={"Accept": Consts.mediaTypeCommitSearchPreview},
)
- def search_topics(self, query, **qualifiers):
+ def search_topics(self, query: str, **qualifiers: Any) -> PaginatedList[Topic]:
"""
:calls: `GET /search/topics `_
:param query: string
:param qualifiers: keyword dict query qualifiers
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Topic.Topic`
+ :rtype: :class:`PaginatedList` of :class:`github.Topic.Topic`
"""
assert isinstance(query, str), query
url_parameters = dict()
@@ -680,7 +669,7 @@ class Github:
url_parameters["q"] = " ".join(query_chunks)
assert url_parameters["q"], "need at least one qualifier"
- return github.PaginatedList.PaginatedList(
+ return PaginatedList(
github.Topic.Topic,
self.__requester,
"/search/topics",
@@ -688,7 +677,7 @@ class Github:
headers={"Accept": Consts.mediaTypeTopicsPreview},
)
- def render_markdown(self, text, context=github.GithubObject.NotSet):
+ def render_markdown(self, text: str, context: Opt[Repository] = NotSet) -> str:
"""
:calls: `POST /markdown `_
:param text: string
@@ -696,78 +685,68 @@ class Github:
:rtype: string
"""
assert isinstance(text, str), text
- assert context is github.GithubObject.NotSet or isinstance(context, github.Repository.Repository), context
+ assert context is NotSet or isinstance(context, github.Repository.Repository), context
post_parameters = {"text": text}
- if context is not github.GithubObject.NotSet:
+ if is_defined(context):
post_parameters["mode"] = "gfm"
post_parameters["context"] = context._identity
status, headers, data = self.__requester.requestJson("POST", "/markdown", input=post_parameters)
return data
- def get_hook(self, name):
+ def get_hook(self, name: str) -> HookDescription:
"""
:calls: `GET /hooks/{name} `_
- :param name: string
- :rtype: :class:`github.HookDescription.HookDescription`
"""
assert isinstance(name, str), name
headers, attributes = self.__requester.requestJsonAndCheck("GET", f"/hooks/{name}")
- return HookDescription.HookDescription(self.__requester, headers, attributes, completed=True)
+ return HookDescription(self.__requester, headers, attributes, completed=True)
- def get_hooks(self):
+ def get_hooks(self) -> list[HookDescription]:
"""
:calls: `GET /hooks `_
:rtype: list of :class:`github.HookDescription.HookDescription`
"""
headers, data = self.__requester.requestJsonAndCheck("GET", "/hooks")
- return [
- HookDescription.HookDescription(self.__requester, headers, attributes, completed=True)
- for attributes in data
- ]
+ return [HookDescription(self.__requester, headers, attributes, completed=True) for attributes in data]
def get_hook_delivery(self, hook_id: int, delivery_id: int) -> HookDelivery:
"""
:calls: `GET /hooks/{hook_id}/deliveries/{delivery_id} `_
:param hook_id: integer
:param delivery_id: integer
- :rtype: :class:`github.HookDelivery.HookDelivery`
+ :rtype: :class:`HookDelivery`
"""
assert isinstance(hook_id, int), hook_id
assert isinstance(delivery_id, int), delivery_id
headers, attributes = self.__requester.requestJsonAndCheck("GET", f"/hooks/{hook_id}/deliveries/{delivery_id}")
- return HookDelivery.HookDelivery(self.__requester, headers, attributes, completed=True)
+ return HookDelivery(self.__requester, headers, attributes, completed=True)
- def get_hook_deliveries(self, hook_id: int) -> List[HookDeliverySummary]:
+ def get_hook_deliveries(self, hook_id: int) -> list[HookDeliverySummary]:
"""
:calls: `GET /hooks/{hook_id}/deliveries `_
:param hook_id: integer
- :rtype: list of :class:`github.HookDelivery.HookDeliverySummary`
+ :rtype: list of :class:`HookDeliverySummary`
"""
assert isinstance(hook_id, int), hook_id
headers, data = self.__requester.requestJsonAndCheck("GET", f"/hooks/{hook_id}/deliveries")
- return [
- HookDelivery.HookDeliverySummary(self.__requester, headers, attributes, completed=True)
- for attributes in data
- ]
+ return [HookDeliverySummary(self.__requester, headers, attributes, completed=True) for attributes in data]
- def get_gitignore_templates(self):
+ def get_gitignore_templates(self) -> list[str]:
"""
:calls: `GET /gitignore/templates `_
- :rtype: list of string
"""
headers, data = self.__requester.requestJsonAndCheck("GET", "/gitignore/templates")
return data
- def get_gitignore_template(self, name):
+ def get_gitignore_template(self, name: str) -> GitignoreTemplate:
"""
:calls: `GET /gitignore/templates/{name} `_
- :rtype: :class:`github.GitignoreTemplate.GitignoreTemplate`
"""
assert isinstance(name, str), name
headers, attributes = self.__requester.requestJsonAndCheck("GET", f"/gitignore/templates/{name}")
- return GitignoreTemplate.GitignoreTemplate(self.__requester, headers, attributes, completed=True)
+ return github.GitignoreTemplate.GitignoreTemplate(self.__requester, headers, attributes, completed=True)
- def get_emojis(self):
+ def get_emojis(self) -> dict[str, str]:
"""
:calls: `GET /emojis `_
:rtype: dictionary of type => url for emoji`
@@ -775,19 +754,24 @@ class Github:
headers, attributes = self.__requester.requestJsonAndCheck("GET", "/emojis")
return attributes
- def create_from_raw_data(self, klass, raw_data, headers={}):
+ def create_from_raw_data(
+ self, klass: type[TGithubObject], raw_data: dict[str, Any], headers: dict[str, str | int] | None = None
+ ) -> TGithubObject:
"""
- Creates an object from raw_data previously obtained by :attr:`github.GithubObject.GithubObject.raw_data`,
- and optionally headers previously obtained by :attr:`github.GithubObject.GithubObject.raw_headers`.
+ Creates an object from raw_data previously obtained by :attr:`GithubObject.raw_data`,
+ and optionally headers previously obtained by :attr:`GithubObject.raw_headers`.
:param klass: the class of the object to create
:param raw_data: dict
:param headers: dict
:rtype: instance of class ``klass``
"""
+ if headers is None:
+ headers = {}
+
return klass(self.__requester, headers, raw_data, completed=True)
- def dump(self, obj, file, protocol=0):
+ def dump(self, obj: GithubObject, file: BinaryIO, protocol: int = 0) -> None:
"""
Dumps (pickles) a PyGithub object to a file-like object.
Some effort is made to not pickle sensitive information like the Github credentials used in the :class:`Github` instance.
@@ -799,7 +783,7 @@ class Github:
"""
pickle.dump((obj.__class__, obj.raw_data, obj.raw_headers), file, protocol)
- def load(self, f):
+ def load(self, f: BinaryIO) -> Any:
"""
Loads (unpickles) a PyGithub object from a file-like object.
@@ -808,7 +792,7 @@ class Github:
"""
return self.create_from_raw_data(*pickle.load(f))
- def get_oauth_application(self, client_id, client_secret):
+ def get_oauth_application(self, client_id: str, client_secret: str) -> ApplicationOAuth:
return github.ApplicationOAuth.ApplicationOAuth(
self.__requester,
headers={},
@@ -816,15 +800,13 @@ class Github:
completed=False,
)
- def get_app(self, slug=github.GithubObject.NotSet):
+ def get_app(self, slug: Opt[str] = NotSet) -> GithubApp:
"""
:calls: `GET /apps/{slug} `_ or `GET /app `_
- :param slug: string
- :rtype: :class:`github.GithubApp.GithubApp`
"""
- assert slug is github.GithubObject.NotSet or isinstance(slug, str), slug
+ assert slug is NotSet or isinstance(slug, str), slug
- if slug is github.GithubObject.NotSet:
+ if slug is NotSet:
# with no slug given, calling /app returns the authenticated app,
# including the actual /apps/{slug}
warnings.warn(
@@ -835,8 +817,4 @@ class Github:
return GithubIntegration(**self.__requester.kwargs).get_app()
else:
# with a slug given, we can lazily load the GithubApp
- return GithubApp.GithubApp(self.__requester, {}, {"url": f"/apps/{slug}"}, completed=False)
-
-
-# Retrocompatibility
-GithubIntegration = github.GithubIntegration
+ return github.GithubApp.GithubApp(self.__requester, {}, {"url": f"/apps/{slug}"}, completed=False)
diff --git a/github/MainClass.pyi b/github/MainClass.pyi
deleted file mode 100644
index 213a9004..00000000
--- a/github/MainClass.pyi
+++ /dev/null
@@ -1,130 +0,0 @@
-from datetime import datetime
-from io import BytesIO
-from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar, Union, overload
-
-from urllib3.util import Retry
-
-from github.AppAuthentication import AppAuthentication
-from github.ApplicationOAuth import ApplicationOAuth
-from github.Auth import Auth
-from github.AuthenticatedUser import AuthenticatedUser
-from github.Commit import Commit
-from github.ContentFile import ContentFile
-from github.Enterprise import Enterprise
-from github.Event import Event
-from github.Gist import Gist
-from github.GithubApp import GithubApp
-from github.GithubObject import GithubObject, _NotSetType
-from github.GitignoreTemplate import GitignoreTemplate
-from github.HookDescription import HookDescription
-from github.Issue import Issue
-from github.License import License
-from github.NamedUser import NamedUser
-from github.Organization import Organization
-from github.PaginatedList import PaginatedList
-from github.Project import Project
-from github.ProjectColumn import ProjectColumn
-from github.RateLimit import RateLimit
-from github.Repository import Repository
-from github.Topic import Topic
-
-TGithubObject = TypeVar("TGithubObject", bound=GithubObject)
-
-DEFAULT_BASE_URL: str
-DEFAULT_STATUS_URL: str
-DEFAULT_TIMEOUT: int
-DEFAULT_PER_PAGE: int
-
-class Github:
- def __init__(
- self,
- login_or_token: Optional[str] = ...,
- password: Optional[str] = ...,
- jwt: Optional[str] = ...,
- app_auth: Optional[AppAuthentication] = ...,
- base_url: str = ...,
- timeout: int = ...,
- user_agent: str = ...,
- per_page: int = ...,
- verify: Union[bool, str] = ...,
- retry: Optional[Union[int, Retry]] = ...,
- pool_size: Optional[int] = ...,
- seconds_between_requests: Optional[float] = ...,
- seconds_between_writes: Optional[float] = ...,
- auth: Optional[Auth] = ...,
- ) -> None: ...
- @property
- def FIX_REPO_GET_GIT_REF(self) -> bool: ...
- @FIX_REPO_GET_GIT_REF.setter
- def FIX_REPO_GET_GIT_REF(self, value: bool) -> None: ...
- @property
- def per_page(self) -> int: ...
- @per_page.setter
- def per_page(self, value: int) -> None: ...
- def create_from_raw_data(
- self,
- klass: Type[TGithubObject],
- raw_data: Dict[str, Any],
- headers: Dict[str, Union[str, int]] = ...,
- ) -> TGithubObject: ...
- def dump(self, obj: GithubObject, file: BytesIO, protocol: int = ...) -> None: ...
- def get_emojis(self) -> Dict[str, str]: ...
- def get_events(self) -> PaginatedList[Event]: ...
- def get_gist(self, id: str) -> Gist: ...
- def get_gists(self, since: Union[datetime, _NotSetType] = ...) -> PaginatedList[Gist]: ...
- def get_gitignore_template(self, name: str) -> GitignoreTemplate: ...
- def get_gitignore_templates(self) -> List[str]: ...
- def get_hook(self, name: str) -> HookDescription: ...
- def get_hooks(self) -> List[HookDescription]: ...
- def get_license(self, key: Union[str, _NotSetType] = ...) -> License: ...
- def get_licenses(self) -> PaginatedList[License]: ...
- def get_organization(self, login: str) -> Organization: ...
- def get_organizations(self, since: Union[int, _NotSetType] = ...) -> PaginatedList[Organization]: ...
- def get_enterprise(self, login: str) -> Enterprise: ...
- def get_project(self, id: int) -> Project: ...
- def get_project_column(self, id: int) -> ProjectColumn: ...
- def get_rate_limit(self) -> RateLimit: ...
- def get_repo(self, full_name_or_id: Union[int, str], lazy: bool = ...) -> Repository: ...
- def get_repos(
- self,
- since: Union[int, _NotSetType] = ...,
- visibility: Union[str, _NotSetType] = ...,
- ) -> PaginatedList[Repository]: ...
- @overload
- def get_user(self, login: _NotSetType = ...) -> AuthenticatedUser: ...
- @overload
- def get_user(self, login: Union[str, _NotSetType] = ...) -> Union[NamedUser, AuthenticatedUser]: ...
- def get_user_by_id(self, user_id: int) -> NamedUser: ...
- def get_users(self, since: Union[int, _NotSetType] = ...) -> PaginatedList[NamedUser]: ...
- def load(self, f: BytesIO) -> Repository: ...
- # argument slug is deprecated, not included here
- def get_app(self) -> GithubApp: ...
- def get_oauth_application(self, client_id: str, client_secret: str) -> ApplicationOAuth: ...
- @property
- def oauth_scopes(self) -> Optional[List[str]]: ...
- @property
- def rate_limiting(self) -> Tuple[int, int]: ...
- @property
- def rate_limiting_resettime(self) -> int: ...
- def render_markdown(self, text: str, context: Union[Repository, _NotSetType] = ...) -> str: ...
- def search_code(
- self,
- query: str,
- sort: Union[str, _NotSetType] = ...,
- order: Union[str, _NotSetType] = ...,
- highlight: bool = ...,
- **qualifiers: Any,
- ) -> PaginatedList[ContentFile]: ...
- def search_commits(
- self, query: str, sort: Union[str, _NotSetType] = ..., order: Union[str, _NotSetType] = ..., **qualifiers: Any
- ) -> PaginatedList[Commit]: ...
- def search_issues(
- self, query: str, sort: Union[str, _NotSetType] = ..., order: Union[str, _NotSetType] = ..., **qualifiers: Any
- ) -> PaginatedList[Issue]: ...
- def search_repositories(
- self, query: str, sort: Union[str, _NotSetType] = ..., order: Union[str, _NotSetType] = ..., **qualifiers: Any
- ) -> PaginatedList[Repository]: ...
- def search_topics(self, query: str, **qualifiers: Any) -> PaginatedList[Topic]: ...
- def search_users(
- self, query: str, sort: Union[str, _NotSetType] = ..., order: Union[str, _NotSetType] = ..., **qualifiers: Any
- ) -> PaginatedList[NamedUser]: ...
diff --git a/github/__init__.py b/github/__init__.py
index d9d2ad24..ceca6297 100644
--- a/github/__init__.py
+++ b/github/__init__.py
@@ -35,6 +35,47 @@ like :class:`github.NamedUser.NamedUser` or :class:`github.Repository.Repository
All classes inherit from :class:`github.GithubObject.GithubObject`.
"""
+import logging
+
+from . import Auth
+from .AppAuthentication import AppAuthentication
+from .GithubException import (
+ BadAttributeException,
+ BadCredentialsException,
+ BadUserAgentException,
+ GithubException,
+ IncompletableObject,
+ RateLimitExceededException,
+ TwoFactorException,
+ UnknownObjectException,
+)
+from .GithubIntegration import GithubIntegration
+from .GithubRetry import GithubRetry
+from .InputFileContent import InputFileContent
+from .InputGitAuthor import InputGitAuthor
+from .InputGitTreeElement import InputGitTreeElement
+from .MainClass import Github
+
+# set log level to INFO for github
+logger = logging.getLogger("github")
+logger.setLevel(logging.INFO)
+logger.addHandler(logging.StreamHandler())
+
+
+def set_log_level(level: int) -> None:
+ """
+ Set the log level of the github logger, e.g. set_log_level(logging.WARNING)
+ :param level: log level
+ """
+ logger.setLevel(level)
+
+
+def enable_console_debug_logging() -> None: # pragma no cover (Function useful only outside test environment)
+ """
+ This function sets up a very simple logging configuration (log everything on standard output) that is useful for troubleshooting.
+ """
+ set_log_level(logging.DEBUG)
+
__all__ = [
"Auth",
@@ -55,45 +96,3 @@ __all__ = [
"TwoFactorException",
"UnknownObjectException",
]
-
-import logging
-
-from github import Auth
-from github.AppAuthentication import AppAuthentication
-from github.GithubIntegration import GithubIntegration
-from github.MainClass import Github
-
-from .GithubException import (
- BadAttributeException,
- BadCredentialsException,
- BadUserAgentException,
- GithubException,
- IncompletableObject,
- RateLimitExceededException,
- TwoFactorException,
- UnknownObjectException,
-)
-from .GithubRetry import GithubRetry
-from .InputFileContent import InputFileContent
-from .InputGitAuthor import InputGitAuthor
-from .InputGitTreeElement import InputGitTreeElement
-
-# set log level to INFO for github
-logger = logging.getLogger("github")
-logger.setLevel(logging.INFO)
-logger.addHandler(logging.StreamHandler())
-
-
-def set_log_level(level: int):
- """
- Set the log level of the github logger, e.g. set_log_level(logging.WARNING)
- :param level: log level
- """
- logger.setLevel(level)
-
-
-def enable_console_debug_logging(): # pragma no cover (Function useful only outside test environment)
- """
- This function sets up a very simple logging configuration (log everything on standard output) that is useful for troubleshooting.
- """
- set_log_level(logging.DEBUG)
diff --git a/github/__init__.pyi b/github/__init__.pyi
deleted file mode 100644
index 198654c9..00000000
--- a/github/__init__.pyi
+++ /dev/null
@@ -1,19 +0,0 @@
-from github import Auth as Auth
-from github.AppAuthentication import AppAuthentication as AppAuthentication
-from github.GithubIntegration import GithubIntegration as GithubIntegration
-from github.GithubRetry import GithubRetry as GithubRetry
-from github.MainClass import Github as Github
-
-from .GithubException import BadAttributeException as BadAttributeException
-from .GithubException import BadCredentialsException as BadCredentialsException
-from .GithubException import BadUserAgentException as BadUserAgentException
-from .GithubException import GithubException as GithubException
-from .GithubException import IncompletableObject as IncompletableObject
-from .GithubException import RateLimitExceededException as RateLimitExceededException
-from .GithubException import TwoFactorException as TwoFactorException
-from .GithubException import UnknownObjectException as UnknownObjectException
-from .InputFileContent import InputFileContent as InputFileContent
-from .InputGitAuthor import InputGitAuthor as InputGitAuthor
-from .InputGitTreeElement import InputGitTreeElement as InputGitTreeElement
-
-def enable_console_debug_logging() -> None: ...