Merge MainClass.pyi and __init__.pyi back to source (#2692)

This commit is contained in:
Trim21
2023-09-07 10:05:00 +02:00
committed by GitHub
parent 8dee53a833
commit f7c0a21ea5
4 changed files with 233 additions and 405 deletions
+192 -214
View File
@@ -47,38 +47,59 @@
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
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 <https://docs.github.com/en/rest/reference/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} <https://docs.github.com/en/rest/reference/licenses#get-a-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 <https://docs.github.com/en/rest/reference/licenses#get-all-commonly-used-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 <https://docs.github.com/en/rest/reference/activity#list-public-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} <https://docs.github.com/en/rest/reference/users>`_ or `GET /user <https://docs.github.com/en/rest/reference/users>`_
: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} <https://docs.github.com/en/rest/reference/users>`_
: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 <https://docs.github.com/en/rest/reference/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} <https://docs.github.com/en/rest/reference/orgs>`_
: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 <https://docs.github.com/en/rest/reference/orgs#list-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} <https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin>`_
: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} <https://docs.github.com/en/rest/reference/repos>`_ or `GET /repositories/{id} <https://docs.github.com/en/rest/reference/repos>`_
: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 <https://docs.github.com/en/rest/reference/repos#list-public-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} <https://docs.github.com/en/rest/reference/projects#get-a-project>`_
: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} <https://docs.github.com/en/rest/reference/projects#get-a-project-column>`_
: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} <https://docs.github.com/en/rest/reference/gists>`_
: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 <https://docs.github.com/en/rest/reference/gists>`_
: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 <https://docs.github.com/en/rest/reference/search>`_
: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 <https://docs.github.com/en/rest/reference/search>`_
: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 <https://docs.github.com/en/rest/reference/search>`_
: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 <https://docs.github.com/en/rest/reference/search>`_
: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 <https://docs.github.com/en/rest/reference/search>`_
: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 <https://docs.github.com/en/rest/reference/search>`_
: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 <https://docs.github.com/en/rest/reference/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} <https://docs.github.com/en/rest/reference/repos#webhooks>`_
: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 <https://docs.github.com/en/rest/reference/repos#webhooks>`_
: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} <https://docs.github.com/en/rest/reference/repos#webhooks>`_
: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 <https://docs.github.com/en/rest/reference/repos#webhooks>`_
: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 <https://docs.github.com/en/rest/reference/gitignore>`_
: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} <https://docs.github.com/en/rest/reference/gitignore>`_
: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 <https://docs.github.com/en/rest/reference/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} <https://docs.github.com/en/rest/reference/apps>`_ or `GET /app <https://docs.github.com/en/rest/reference/apps>`_
: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)
-130
View File
@@ -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]: ...
+41 -42
View File
@@ -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)
-19
View File
@@ -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: ...