Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions doc/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ Breaking Changes

gh.get_rate_limit().resources.core.remaining

Deprecations
^^^^^^^^^^^^

* Methods ``dismissal_users`` and ``dismissal_teams`` of ``RequiredPullRequestReviews`` are deprecated,
use ``dismissal_restrictions.users`` and ``dismissal_restrictions.teams`` instead.

Version 2.6.0 (February 15, 2025)
---------------------------------

Expand All @@ -49,6 +55,24 @@ Breaking Changes
repo.get_views_traffic().views.timestamp
repo.get_clones_traffic().clones.timestamp

* Add ``GitCommitVerification`` class (`#3028 <https://github.com/PyGithub/PyGithub/pull/3028>`_) (`822e6d71 <https://github.com/PyGithub/PyGithub/commit/822e6d71>`_):

Changes the return value of ``GitTag.verification`` and ``GitCommit.verification`` from ``dict`` to ``GitCommitVerification``.

Code like

.. code-block:: python

tag.verification["reason"]
commit.verification["reason"]

should be replaced with

.. code-block:: python

tag.verification.reason
commit.verification.reason

* Property ``AppAuth.private_key`` has been removed (`#3065 <https://github.com/PyGithub/PyGithub/pull/3065>`_) (`36697b22 <https://github.com/PyGithub/PyGithub/commit/36697b22>`_)

* Fix typos (`#3086 <https://github.com/PyGithub/PyGithub/pull/3086>`_) (`a50ae51b <https://github.com/PyGithub/PyGithub/commit/a50ae51b>`_):
Expand Down
8 changes: 3 additions & 5 deletions github/AppAuthentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################


from typing import Dict, Optional, Union
from __future__ import annotations

import deprecated

Expand All @@ -45,10 +43,10 @@
class AppAuthentication(AppInstallationAuth):
def __init__(
self,
app_id: Union[int, str],
app_id: int | str,
private_key: str,
installation_id: int,
token_permissions: Optional[Dict[str, str]] = None,
token_permissions: dict[str, str] | None = None,
):
super().__init__(
app_auth=AppAuth(app_id, private_key),
Expand Down
8 changes: 4 additions & 4 deletions github/ApplicationOAuth.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ class ApplicationOAuth(NonCompletableGithubObject):

"""

def _initAttributes(self) -> None:
self._client_id: Attribute[str] = NotSet
self._client_secret: Attribute[str] = NotSet

def __init__(
self,
requester: Requester,
Expand All @@ -68,6 +64,10 @@ def __init__(
requester = requester.withAuth(auth=None)
super().__init__(requester, headers, attributes)

def _initAttributes(self) -> None:
self._client_id: Attribute[str] = NotSet
self._client_secret: Attribute[str] = NotSet

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

Expand Down
71 changes: 36 additions & 35 deletions github/Auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
from __future__ import annotations

import abc
import base64
import time
from abc import ABC
from datetime import datetime, timedelta, timezone
from typing import TYPE_CHECKING, Callable, Dict, Optional, Union
from typing import TYPE_CHECKING, Callable, Union

import jwt
from requests import utils
Expand Down Expand Up @@ -187,11 +188,11 @@ def token_type(self) -> str:


class JwtSigner:
def __init__(self, private_key_or_func: Union[str, PrivateKeyGenerator], jwt_algorithm: str):
def __init__(self, private_key_or_func: str | PrivateKeyGenerator, jwt_algorithm: str):
self._private_key_or_func = private_key_or_func
self._jwt_algorithm = jwt_algorithm

def jwt_sign(self, payload: dict) -> Union[str, bytes]:
def jwt_sign(self, payload: dict) -> str | bytes:
if callable(self._private_key_or_func):
private_key = self._private_key_or_func()
else:
Expand All @@ -208,16 +209,16 @@ class AppAuth(JWT):
"""

@staticmethod
def create_jwt_sign(private_key_or_func: Union[str, PrivateKeyGenerator], jwt_algorithm: str) -> DictSignFunction:
def create_jwt_sign(private_key_or_func: str | PrivateKeyGenerator, jwt_algorithm: str) -> DictSignFunction:
return JwtSigner(private_key_or_func, jwt_algorithm).jwt_sign

# v3: move * above private_key
def __init__(
self,
app_id: Union[int, str],
private_key: Optional[Union[str, PrivateKeyGenerator]] = None,
app_id: int | str,
private_key: str | PrivateKeyGenerator | None = None,
*,
sign_func: Optional[DictSignFunction] = None,
sign_func: DictSignFunction | None = None,
jwt_expiry: int = Consts.DEFAULT_JWT_EXPIRY,
jwt_issued_at: int = Consts.DEFAULT_JWT_ISSUED_AT,
):
Expand All @@ -240,7 +241,7 @@ def __init__(
self._jwt_issued_at = jwt_issued_at

@property
def app_id(self) -> Union[int, str]:
def app_id(self) -> int | str:
return self._app_id

@property
Expand All @@ -250,9 +251,9 @@ def token(self) -> str:
def get_installation_auth(
self,
installation_id: int,
token_permissions: Optional[Dict[str, str]] = None,
requester: Optional[Requester] = None,
) -> "AppInstallationAuth":
token_permissions: dict[str, str] | None = None,
requester: Requester | None = None,
) -> AppInstallationAuth:
"""
Creates a github.Auth.AppInstallationAuth instance for an installation.

Expand All @@ -264,7 +265,7 @@ def get_installation_auth(
"""
return AppInstallationAuth(self, installation_id, token_permissions, requester)

def create_jwt(self, expiration: Optional[int] = None) -> str:
def create_jwt(self, expiration: int | None = None) -> str:
"""
Create a signed JWT
https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-a-github-app
Expand Down Expand Up @@ -316,15 +317,15 @@ class AppInstallationAuth(Auth, WithRequester["AppInstallationAuth"]):
"""

# used to fetch live access token when calling self.token
__integration: Optional["GithubIntegration"] = None
__installation_authorization: Optional[InstallationAuthorization] = None
__integration: GithubIntegration | None = None
__installation_authorization: InstallationAuthorization | None = None

def __init__(
self,
app_auth: AppAuth,
installation_id: int,
token_permissions: Optional[Dict[str, str]] = None,
requester: Optional[Requester] = None,
token_permissions: dict[str, str] | None = None,
requester: Requester | None = None,
):
super().__init__()

Expand All @@ -340,7 +341,7 @@ def __init__(
if requester is not None:
self.withRequester(requester)

def withRequester(self, requester: Requester) -> "AppInstallationAuth":
def withRequester(self, requester: Requester) -> AppInstallationAuth:
assert isinstance(requester, Requester), requester
super().withRequester(requester.withAuth(self._app_auth))

Expand All @@ -352,15 +353,15 @@ def withRequester(self, requester: Requester) -> "AppInstallationAuth":
return self

@property
def app_id(self) -> Union[int, str]:
def app_id(self) -> int | str:
return self._app_auth.app_id

@property
def installation_id(self) -> int:
return self._installation_id

@property
def token_permissions(self) -> Optional[Dict[str, str]]:
def token_permissions(self) -> dict[str, str] | None:
return self._token_permissions

@property
Expand Down Expand Up @@ -403,10 +404,10 @@ class AppUserAuth(Auth, WithRequester["AppUserAuth"]):
_client_secret: str
_token: str
_type: str
_scope: Optional[str]
_expires_at: Optional[datetime]
_refresh_token: Optional[str]
_refresh_expires_at: Optional[datetime]
_scope: str | None
_expires_at: datetime | None
_refresh_token: str | None
_refresh_expires_at: datetime | None

# imported here to avoid circular import
from github.ApplicationOAuth import ApplicationOAuth
Expand All @@ -418,11 +419,11 @@ def __init__(
client_id: str,
client_secret: str,
token: str,
token_type: Optional[str] = None,
expires_at: Optional[datetime] = None,
refresh_token: Optional[str] = None,
refresh_expires_at: Optional[datetime] = None,
requester: Optional[Requester] = None,
token_type: str | None = None,
expires_at: datetime | None = None,
refresh_token: str | None = None,
refresh_expires_at: datetime | None = None,
requester: Requester | None = None,
) -> None:
super().__init__()

Expand Down Expand Up @@ -456,7 +457,7 @@ def token(self) -> str:
self._refresh()
return self._token

def withRequester(self, requester: Requester) -> "AppUserAuth":
def withRequester(self, requester: Requester) -> AppUserAuth:
assert isinstance(requester, Requester), requester
super().withRequester(requester.withAuth(None))

Expand Down Expand Up @@ -497,15 +498,15 @@ def _refresh(self) -> None:
self._refresh_expires_at = token.refresh_expires_at

@property
def expires_at(self) -> Optional[datetime]:
def expires_at(self) -> datetime | None:
return self._expires_at

@property
def refresh_token(self) -> Optional[str]:
def refresh_token(self) -> str | None:
return self._refresh_token

@property
def refresh_expires_at(self) -> Optional[datetime]:
def refresh_expires_at(self) -> datetime | None:
return self._refresh_expires_at

@property
Expand All @@ -521,8 +522,8 @@ class NetrcAuth(HTTPBasicAuth, WithRequester["NetrcAuth"]):
def __init__(self) -> None:
super().__init__()

self._login: Optional[str] = None
self._password: Optional[str] = None
self._login: str | None = None
self._password: str | None = None

@property
def username(self) -> str:
Expand All @@ -538,7 +539,7 @@ def password(self) -> str:
assert self._password is not None, "Method withRequester(Requester) must be called first"
return self._password

def withRequester(self, requester: Requester) -> "NetrcAuth":
def withRequester(self, requester: Requester) -> NetrcAuth:
assert isinstance(requester, Requester), requester
super().withRequester(requester)

Expand Down
5 changes: 3 additions & 2 deletions github/AuthorizationApplication.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
from __future__ import annotations

from typing import Any, Dict
from typing import Any

from github.GithubObject import Attribute, CompletableGithubObject, NotSet

Expand All @@ -62,7 +63,7 @@ def url(self) -> str:
self._completeIfNotSet(self._url)
return self._url.value

def _useAttributes(self, attributes: Dict[str, Any]) -> None:
def _useAttributes(self, attributes: dict[str, Any]) -> None:
if "name" in attributes: # pragma no branch
self._name = self._makeStringAttribute(attributes["name"])
if "url" in attributes: # pragma no branch
Expand Down
5 changes: 3 additions & 2 deletions github/Autolink.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
from __future__ import annotations

from typing import Any, Dict
from typing import Any

from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet

Expand Down Expand Up @@ -81,7 +82,7 @@ def key_prefix(self) -> str:
def url_template(self) -> str:
return self._url_template.value

def _useAttributes(self, attributes: Dict[str, Any]) -> None:
def _useAttributes(self, attributes: dict[str, Any]) -> None:
if "id" in attributes: # pragma no branch
self._id = self._makeIntAttribute(attributes["id"])
if "is_alphanumeric" in attributes: # pragma no branch
Expand Down
6 changes: 4 additions & 2 deletions github/Branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ def edit_required_pull_request_reviews(
require_code_owner_reviews: Opt[bool] = NotSet,
required_approving_review_count: Opt[int] = NotSet,
require_last_push_approval: Opt[bool] = NotSet,
) -> RequiredStatusChecks:
) -> RequiredPullRequestReviews:
"""
:calls: `PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews <https://docs.github.com/en/rest/reference/repos#branches>`_
"""
Expand Down Expand Up @@ -460,7 +460,9 @@ def edit_required_pull_request_reviews(
input=post_parameters,
)

return github.RequiredStatusChecks.RequiredStatusChecks(self._requester, headers, data, completed=True)
return github.RequiredPullRequestReviews.RequiredPullRequestReviews(
self._requester, headers, data, completed=True
)

def remove_required_pull_request_reviews(self) -> None:
"""
Expand Down
5 changes: 3 additions & 2 deletions github/CVSS.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
from __future__ import annotations

from decimal import Decimal
from typing import Any, Dict
from typing import Any

from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet

Expand Down Expand Up @@ -71,7 +72,7 @@ def vector_string(self) -> str:
def version(self) -> Decimal:
return self._version.value

def _useAttributes(self, attributes: Dict[str, Any]) -> None:
def _useAttributes(self, attributes: dict[str, Any]) -> None:
if "score" in attributes and attributes["score"] is not None: # pragma no branch
# ensure string so we don't have all the float extra nonsense
self._score = self._makeDecimalAttribute(Decimal(str(attributes["score"])))
Expand Down
6 changes: 3 additions & 3 deletions github/CWE.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
from __future__ import annotations


from typing import Any, Dict
from typing import Any

from github.GithubObject import Attribute, CompletableGithubObject, NotSet

Expand All @@ -65,7 +65,7 @@ def cwe_id(self) -> str:
def name(self) -> str:
return self._name.value

def _useAttributes(self, attributes: Dict[str, Any]) -> None:
def _useAttributes(self, attributes: dict[str, Any]) -> None:
if "cwe_id" in attributes: # pragma no branch
self._cwe_id = self._makeStringAttribute(attributes["cwe_id"])
if "name" in attributes: # pragma no branch
Expand Down
Loading