diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 5a471c08..caa0bb2d 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -15,6 +15,7 @@ jobs:
python-version: "3.x"
- run: |
python -m pip install --upgrade pip
+ pip install -r requirements.txt
pip install -r requirements-types.txt
- uses: liskin/gh-problem-matcher-wrap@v2
with:
diff --git a/.isort.cfg b/.isort.cfg
index aa9496b0..58fc9801 100644
--- a/.isort.cfg
+++ b/.isort.cfg
@@ -4,5 +4,5 @@ include_trailing_comma=True
force_grid_wrap=0
use_parentheses=True
line_length=88
-known_third_party=dateutil,deprecated,httpretty,jwt,nacl,pytest,requests,setuptools,urllib3
+known_third_party=dateutil,deprecated,httpretty,jwt,nacl,pytest,requests,setuptools,typing_extensions,urllib3
known_first_party=github
diff --git a/github/Branch.py b/github/Branch.py
index bfba5b7f..a3836199 100644
--- a/github/Branch.py
+++ b/github/Branch.py
@@ -30,17 +30,37 @@
# along with PyGithub. If not, see . #
# #
################################################################################
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any
import github.BranchProtection
import github.Commit
-import github.GithubObject
import github.RequiredPullRequestReviews
import github.RequiredStatusChecks
+from github import Consts
+from github.GithubObject import (
+ Attribute,
+ NonCompletableGithubObject,
+ NotSet,
+ Opt,
+ is_defined,
+ is_optional,
+ is_optional_list,
+ is_undefined,
+)
-from . import Consts
+if TYPE_CHECKING:
+ from github.BranchProtection import BranchProtection
+ from github.Commit import Commit
+ from github.NamedUser import NamedUser
+ from github.PaginatedList import PaginatedList
+ from github.RequiredPullRequestReviews import RequiredPullRequestReviews
+ from github.RequiredStatusChecks import RequiredStatusChecks
+ from github.Team import Team
-class Branch(github.GithubObject.NonCompletableGithubObject):
+class Branch(NonCompletableGithubObject):
"""
This class represents Branches. The reference can be found here https://docs.github.com/en/rest/reference/repos#branches
"""
@@ -49,40 +69,28 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
return self.get__repr__({"name": self._name.value})
@property
- def commit(self):
- """
- :type: :class:`github.Commit.Commit`
- """
+ def commit(self) -> Commit:
return self._commit.value
@property
- def name(self):
- """
- :type: string
- """
+ def name(self) -> str:
return self._name.value
@property
- def protected(self):
- """
- :type: bool
- """
+ def protected(self) -> bool:
return self._protected.value
@property
- def protection_url(self):
- """
- :type: string
- """
+ def protection_url(self) -> str:
return self._protection_url.value
- def _initAttributes(self):
- self._commit = github.GithubObject.NotSet
- self._name = github.GithubObject.NotSet
- self._protection_url = github.GithubObject.NotSet
- self._protected = github.GithubObject.NotSet
+ def _initAttributes(self) -> None:
+ self._commit: Attribute[Commit] = github.GithubObject.NotSet
+ self._name: Attribute[str] = github.GithubObject.NotSet
+ self._protection_url: Attribute[str] = github.GithubObject.NotSet
+ self._protected: Attribute[bool] = github.GithubObject.NotSet
- def _useAttributes(self, attributes):
+ def _useAttributes(self, attributes) -> None:
if "commit" in attributes: # pragma no branch
self._commit = self._makeClassAttribute(
github.Commit.Commit, attributes["commit"]
@@ -96,7 +104,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
if "protected" in attributes: # pragma no branch
self._protected = self._makeBoolAttribute(attributes["protected"])
- def get_protection(self):
+ def get_protection(self) -> BranchProtection:
"""
:calls: `GET /repos/{owner}/{repo}/branches/{branch}/protection `_
"""
@@ -111,124 +119,68 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
def edit_protection(
self,
- strict=github.GithubObject.NotSet,
- contexts=github.GithubObject.NotSet,
- enforce_admins=github.GithubObject.NotSet,
- dismissal_users=github.GithubObject.NotSet,
- dismissal_teams=github.GithubObject.NotSet,
- dismissal_apps=github.GithubObject.NotSet,
- dismiss_stale_reviews=github.GithubObject.NotSet,
- require_code_owner_reviews=github.GithubObject.NotSet,
- required_approving_review_count=github.GithubObject.NotSet,
- user_push_restrictions=github.GithubObject.NotSet,
- team_push_restrictions=github.GithubObject.NotSet,
- app_push_restrictions=github.GithubObject.NotSet,
- required_linear_history=github.GithubObject.NotSet,
- allow_force_pushes=github.GithubObject.NotSet,
- required_conversation_resolution=github.GithubObject.NotSet,
- lock_branch=github.GithubObject.NotSet,
- allow_fork_syncing=github.GithubObject.NotSet,
- users_bypass_pull_request_allowances=github.GithubObject.NotSet,
- teams_bypass_pull_request_allowances=github.GithubObject.NotSet,
- apps_bypass_pull_request_allowances=github.GithubObject.NotSet,
- block_creations=github.GithubObject.NotSet,
+ strict: Opt[bool] = NotSet,
+ contexts: Opt[list[str]] = NotSet,
+ enforce_admins: Opt[bool] = NotSet,
+ dismissal_users: Opt[list[str]] = NotSet,
+ dismissal_teams: Opt[list[str]] = NotSet,
+ dismissal_apps: Opt[list[str]] = NotSet,
+ dismiss_stale_reviews: Opt[bool] = NotSet,
+ require_code_owner_reviews: Opt[bool] = NotSet,
+ required_approving_review_count: Opt[int] = NotSet,
+ user_push_restrictions: Opt[list[str]] = NotSet,
+ team_push_restrictions: Opt[list[str]] = NotSet,
+ app_push_restrictions: Opt[list[str]] = NotSet,
+ required_linear_history: Opt[bool] = NotSet,
+ allow_force_pushes: Opt[bool] = NotSet,
+ required_conversation_resolution: Opt[bool] = NotSet,
+ lock_branch: Opt[bool] = NotSet,
+ allow_fork_syncing: Opt[bool] = NotSet,
+ users_bypass_pull_request_allowances: Opt[list[str]] = NotSet,
+ teams_bypass_pull_request_allowances: Opt[list[str]] = NotSet,
+ apps_bypass_pull_request_allowances: Opt[list[str]] = NotSet,
+ block_creations: Opt[bool] = NotSet,
):
"""
:calls: `PUT /repos/{owner}/{repo}/branches/{branch}/protection `_
- :strict: bool
- :contexts: list of strings
- :enforce_admins: bool
- :dismissal_users: list of strings
- :dismissal_teams: list of strings
- :dismissal_apps: list of strings
- :dismiss_stale_reviews: bool
- :require_code_owner_reviews: bool
- :required_approving_review_count: int
- :user_push_restrictions: list of strings
- :team_push_restrictions: list of strings
- :app_push_restrictions: list of strings
- :required_linear_history: bool
- :allow_force_pushes: bool
- :required_conversation_resolution: bool
- :lock_branch: bool
- :allow_fork_syncing: bool
- :users_bypass_pull_request_allowances: list of strings
- :teams_bypass_pull_request_allowances: list of strings
- :apps_bypass_pull_request_allowances: list of strings
- :block_creations: bool
NOTE: The GitHub API groups strict and contexts together, both must
be submitted. Take care to pass both as arguments even if only one is
changing. Use edit_required_status_checks() to avoid this.
"""
- assert strict is github.GithubObject.NotSet or isinstance(strict, bool), strict
- assert contexts is github.GithubObject.NotSet or all(
- isinstance(element, str) for element in contexts
- ), contexts
- assert enforce_admins is github.GithubObject.NotSet or isinstance(
- enforce_admins, bool
- ), enforce_admins
- assert dismissal_users is github.GithubObject.NotSet or all(
- isinstance(element, str) for element in dismissal_users
- ), dismissal_users
- assert dismissal_teams is github.GithubObject.NotSet or all(
- isinstance(element, str) for element in dismissal_teams
- ), dismissal_teams
- assert dismissal_apps is github.GithubObject.NotSet or all(
- isinstance(element, str) for element in dismissal_apps
- ), dismissal_apps
- assert dismiss_stale_reviews is github.GithubObject.NotSet or isinstance(
- dismiss_stale_reviews, bool
- ), dismiss_stale_reviews
- assert require_code_owner_reviews is github.GithubObject.NotSet or isinstance(
- require_code_owner_reviews, bool
- ), require_code_owner_reviews
- assert (
- required_approving_review_count is github.GithubObject.NotSet
- or isinstance(required_approving_review_count, int)
- ), (required_approving_review_count)
- assert required_linear_history is github.GithubObject.NotSet or isinstance(
+ assert is_optional(strict, bool), strict
+ assert is_optional_list(contexts, str), contexts
+ assert is_optional(enforce_admins, bool), enforce_admins
+ assert is_optional_list(dismissal_users, str), dismissal_users
+ assert is_optional_list(dismissal_teams, str), dismissal_teams
+ assert is_optional_list(dismissal_apps, str), dismissal_apps
+ assert is_optional(dismiss_stale_reviews, bool), dismiss_stale_reviews
+ assert is_optional(require_code_owner_reviews, bool), require_code_owner_reviews
+ assert is_optional(
+ required_approving_review_count, int
+ ), required_approving_review_count
+ assert is_optional(required_linear_history, bool), required_linear_history
+ assert is_optional(allow_force_pushes, bool), allow_force_pushes
+ assert is_optional(
required_linear_history, bool
- ), required_linear_history
- assert allow_force_pushes is github.GithubObject.NotSet or isinstance(
- allow_force_pushes, bool
- ), allow_force_pushes
- assert (
- required_conversation_resolution is github.GithubObject.NotSet
- or isinstance(required_linear_history, bool)
), required_conversation_resolution
- assert lock_branch is github.GithubObject.NotSet or isinstance(
- lock_branch, bool
- ), lock_branch
- assert allow_fork_syncing is github.GithubObject.NotSet or isinstance(
- allow_fork_syncing, bool
- ), allow_fork_syncing
- assert (
- users_bypass_pull_request_allowances is github.GithubObject.NotSet
- or all(
- isinstance(element, str)
- for element in users_bypass_pull_request_allowances
- )
- ), (users_bypass_pull_request_allowances)
- assert (
- teams_bypass_pull_request_allowances is github.GithubObject.NotSet
- or all(
- isinstance(element, str)
- for element in teams_bypass_pull_request_allowances
- )
- ), (teams_bypass_pull_request_allowances)
- assert apps_bypass_pull_request_allowances is github.GithubObject.NotSet or all(
- isinstance(element, str) for element in apps_bypass_pull_request_allowances
+ assert is_optional(lock_branch, bool), lock_branch
+ assert is_optional(allow_fork_syncing, bool), allow_fork_syncing
+ assert is_optional_list(
+ users_bypass_pull_request_allowances, str
+ ), users_bypass_pull_request_allowances
+ assert is_optional_list(
+ teams_bypass_pull_request_allowances, str
+ ), teams_bypass_pull_request_allowances
+ assert is_optional_list(
+ apps_bypass_pull_request_allowances, str
), apps_bypass_pull_request_allowances
- post_parameters = {}
- if (
- strict is not github.GithubObject.NotSet
- or contexts is not github.GithubObject.NotSet
- ):
- if strict is github.GithubObject.NotSet:
+ post_parameters: dict[str, Any] = {}
+ if is_defined(strict) or is_defined(contexts):
+ if is_undefined(strict):
strict = False
- if contexts is github.GithubObject.NotSet:
+ if is_undefined(contexts):
contexts = []
post_parameters["required_status_checks"] = {
"strict": strict,
@@ -237,42 +189,42 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
else:
post_parameters["required_status_checks"] = None
- if enforce_admins is not github.GithubObject.NotSet:
+ if is_defined(enforce_admins):
post_parameters["enforce_admins"] = enforce_admins
else:
post_parameters["enforce_admins"] = None
if (
- dismissal_users is not github.GithubObject.NotSet
- or dismissal_teams is not github.GithubObject.NotSet
- or dismissal_apps is not github.GithubObject.NotSet
- or dismiss_stale_reviews is not github.GithubObject.NotSet
- or require_code_owner_reviews is not github.GithubObject.NotSet
- or required_approving_review_count is not github.GithubObject.NotSet
- or users_bypass_pull_request_allowances is not github.GithubObject.NotSet
- or teams_bypass_pull_request_allowances is not github.GithubObject.NotSet
- or apps_bypass_pull_request_allowances is not github.GithubObject.NotSet
+ is_defined(dismissal_users)
+ or is_defined(dismissal_teams)
+ or is_defined(dismissal_apps)
+ or is_defined(dismiss_stale_reviews)
+ or is_defined(require_code_owner_reviews)
+ or is_defined(required_approving_review_count)
+ or is_defined(users_bypass_pull_request_allowances)
+ or is_defined(teams_bypass_pull_request_allowances)
+ or is_defined(apps_bypass_pull_request_allowances)
):
post_parameters["required_pull_request_reviews"] = {}
- if dismiss_stale_reviews is not github.GithubObject.NotSet:
+ if is_defined(dismiss_stale_reviews):
post_parameters["required_pull_request_reviews"][
"dismiss_stale_reviews"
] = dismiss_stale_reviews
- if require_code_owner_reviews is not github.GithubObject.NotSet:
+ if is_defined(require_code_owner_reviews):
post_parameters["required_pull_request_reviews"][
"require_code_owner_reviews"
] = require_code_owner_reviews
- if required_approving_review_count is not github.GithubObject.NotSet:
+ if is_defined(required_approving_review_count):
post_parameters["required_pull_request_reviews"][
"required_approving_review_count"
] = required_approving_review_count
dismissal_restrictions = {}
- if dismissal_users is not github.GithubObject.NotSet:
+ if is_defined(dismissal_users):
dismissal_restrictions["users"] = dismissal_users
- if dismissal_teams is not github.GithubObject.NotSet:
+ if is_defined(dismissal_teams):
dismissal_restrictions["teams"] = dismissal_teams
- if dismissal_apps is not github.GithubObject.NotSet:
+ if is_defined(dismissal_apps):
dismissal_restrictions["apps"] = dismissal_apps
if dismissal_restrictions:
@@ -281,15 +233,15 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
] = dismissal_restrictions
bypass_pull_request_allowances = {}
- if users_bypass_pull_request_allowances is not github.GithubObject.NotSet:
+ if is_defined(users_bypass_pull_request_allowances):
bypass_pull_request_allowances[
"users"
] = users_bypass_pull_request_allowances
- if teams_bypass_pull_request_allowances is not github.GithubObject.NotSet:
+ if is_defined(teams_bypass_pull_request_allowances):
bypass_pull_request_allowances[
"teams"
] = teams_bypass_pull_request_allowances
- if apps_bypass_pull_request_allowances is not github.GithubObject.NotSet:
+ if is_defined(apps_bypass_pull_request_allowances):
bypass_pull_request_allowances[
"apps"
] = apps_bypass_pull_request_allowances
@@ -301,15 +253,15 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
else:
post_parameters["required_pull_request_reviews"] = None
if (
- user_push_restrictions is not github.GithubObject.NotSet
- or team_push_restrictions is not github.GithubObject.NotSet
- or app_push_restrictions is not github.GithubObject.NotSet
+ is_defined(user_push_restrictions)
+ or is_defined(team_push_restrictions)
+ or is_defined(app_push_restrictions)
):
- if user_push_restrictions is github.GithubObject.NotSet:
+ if is_undefined(user_push_restrictions):
user_push_restrictions = []
- if team_push_restrictions is github.GithubObject.NotSet:
+ if is_undefined(team_push_restrictions):
team_push_restrictions = []
- if app_push_restrictions is github.GithubObject.NotSet:
+ if is_undefined(app_push_restrictions):
app_push_restrictions = []
post_parameters["restrictions"] = {
"users": user_push_restrictions,
@@ -318,29 +270,29 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
}
else:
post_parameters["restrictions"] = None
- if required_linear_history is not github.GithubObject.NotSet:
+ if is_defined(required_linear_history):
post_parameters["required_linear_history"] = required_linear_history
else:
post_parameters["required_linear_history"] = None
- if allow_force_pushes is not github.GithubObject.NotSet:
+ if is_defined(allow_force_pushes):
post_parameters["allow_force_pushes"] = allow_force_pushes
else:
post_parameters["allow_force_pushes"] = None
- if required_conversation_resolution is not github.GithubObject.NotSet:
+ if is_defined(required_conversation_resolution):
post_parameters[
"required_conversation_resolution"
] = required_conversation_resolution
else:
post_parameters["required_conversation_resolution"] = None
- if lock_branch is not github.GithubObject.NotSet:
+ if is_defined(lock_branch):
post_parameters["lock_branch"] = lock_branch
else:
post_parameters["lock_branch"] = None
- if allow_fork_syncing is not github.GithubObject.NotSet:
+ if is_defined(allow_fork_syncing):
post_parameters["allow_fork_syncing"] = allow_fork_syncing
else:
post_parameters["allow_fork_syncing"] = None
- if block_creations is not github.GithubObject.NotSet:
+ if is_defined(block_creations):
post_parameters["block_creations"] = block_creations
else:
post_parameters["block_creations"] = None
@@ -352,7 +304,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
input=post_parameters,
)
- def remove_protection(self):
+ def remove_protection(self) -> None:
"""
:calls: `DELETE /repos/{owner}/{repo}/branches/{branch}/protection `_
"""
@@ -361,7 +313,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
self.protection_url,
)
- def get_required_status_checks(self):
+ def get_required_status_checks(self) -> RequiredStatusChecks:
"""
:calls: `GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks `_
:rtype: :class:`github.RequiredStatusChecks.RequiredStatusChecks`
@@ -374,23 +326,19 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
)
def edit_required_status_checks(
- self, strict=github.GithubObject.NotSet, contexts=github.GithubObject.NotSet
+ self,
+ strict: Opt[bool] = NotSet,
+ contexts: Opt[list[str]] = NotSet,
):
"""
:calls: `PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks `_
- :strict: bool
- :contexts: list of strings
"""
- assert strict is github.GithubObject.NotSet or isinstance(strict, bool), strict
- assert contexts is github.GithubObject.NotSet or all(
- isinstance(element, str) for element in contexts
- ), contexts
+ assert is_optional(strict, bool), strict
+ assert is_optional_list(contexts, str), contexts
- post_parameters = {}
- if strict is not github.GithubObject.NotSet:
- post_parameters["strict"] = strict
- if contexts is not github.GithubObject.NotSet:
- post_parameters["contexts"] = contexts
+ post_parameters: dict[str, Any] = NotSet.remove_unset_items(
+ {"strict": strict, "contexts": contexts}
+ )
headers, data = self._requester.requestJsonAndCheck(
"PATCH",
f"{self.protection_url}/required_status_checks",
@@ -406,10 +354,9 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
f"{self.protection_url}/required_status_checks",
)
- def get_required_pull_request_reviews(self):
+ def get_required_pull_request_reviews(self) -> RequiredPullRequestReviews:
"""
:calls: `GET /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews `_
- :rtype: :class:`github.RequiredPullRequestReviews.RequiredPullRequestReviews`
"""
headers, data = self._requester.requestJsonAndCheck(
"GET",
@@ -422,62 +369,39 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
def edit_required_pull_request_reviews(
self,
- dismissal_users=github.GithubObject.NotSet,
- dismissal_teams=github.GithubObject.NotSet,
- dismissal_apps=github.GithubObject.NotSet,
- dismiss_stale_reviews=github.GithubObject.NotSet,
- require_code_owner_reviews=github.GithubObject.NotSet,
- required_approving_review_count=github.GithubObject.NotSet,
+ dismissal_users: Opt[list[str]] = NotSet,
+ dismissal_teams: Opt[list[str]] = NotSet,
+ dismissal_apps: Opt[list[str]] = NotSet,
+ dismiss_stale_reviews: Opt[bool] = NotSet,
+ require_code_owner_reviews: Opt[bool] = NotSet,
+ required_approving_review_count: Opt[int] = NotSet,
):
"""
:calls: `PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews `_
- :dismissal_users: list of strings
- :dismissal_teams: list of strings
- :dismissal_apps: list of strings
- :dismiss_stale_reviews: bool
- :require_code_owner_reviews: bool
- :required_approving_review_count: int
"""
- assert dismissal_users is github.GithubObject.NotSet or all(
- isinstance(element, str) for element in dismissal_users
- ), dismissal_users
- assert dismissal_teams is github.GithubObject.NotSet or all(
- isinstance(element, str) for element in dismissal_teams
- ), dismissal_teams
- assert dismiss_stale_reviews is github.GithubObject.NotSet or isinstance(
- dismiss_stale_reviews, bool
- ), dismiss_stale_reviews
- assert require_code_owner_reviews is github.GithubObject.NotSet or isinstance(
- require_code_owner_reviews, bool
- ), require_code_owner_reviews
- assert (
- required_approving_review_count is github.GithubObject.NotSet
- or isinstance(required_approving_review_count, int)
- ), (required_approving_review_count)
+ assert is_optional_list(dismissal_users, str), dismissal_users
+ assert is_optional_list(dismissal_teams, str), dismissal_teams
+ assert is_optional(dismiss_stale_reviews, bool), dismiss_stale_reviews
+ assert is_optional(require_code_owner_reviews, bool), require_code_owner_reviews
+ assert is_optional(
+ required_approving_review_count, int
+ ), required_approving_review_count
- post_parameters = {}
- if (
- dismissal_users is not github.GithubObject.NotSet
- or dismissal_teams is not github.GithubObject.NotSet
- or dismissal_apps is not github.GithubObject.NotSet
- ):
- post_parameters["dismissal_restrictions"] = {}
+ post_parameters: dict[str, Any] = NotSet.remove_unset_items(
+ {
+ "dismiss_stale_reviews": dismiss_stale_reviews,
+ "require_code_owner_reviews": require_code_owner_reviews,
+ "required_approving_review_count": required_approving_review_count,
+ }
+ )
- if dismissal_users is not github.GithubObject.NotSet:
- post_parameters["dismissal_restrictions"]["users"] = dismissal_users
- if dismissal_teams is not github.GithubObject.NotSet:
- post_parameters["dismissal_restrictions"]["teams"] = dismissal_teams
- if dismissal_apps is not github.GithubObject.NotSet:
- post_parameters["dismissal_restrictions"]["apps"] = dismissal_apps
+ dismissal_restrictions: dict[str, Any] = NotSet.remove_unset_items(
+ {"users": dismissal_users, "teams": dismissal_teams, "apps": dismissal_apps}
+ )
+
+ if dismissal_restrictions:
+ post_parameters["dismissal_restrictions"] = dismissal_restrictions
- if dismiss_stale_reviews is not github.GithubObject.NotSet:
- post_parameters["dismiss_stale_reviews"] = dismiss_stale_reviews
- if require_code_owner_reviews is not github.GithubObject.NotSet:
- post_parameters["require_code_owner_reviews"] = require_code_owner_reviews
- if required_approving_review_count is not github.GithubObject.NotSet:
- post_parameters[
- "required_approving_review_count"
- ] = required_approving_review_count
headers, data = self._requester.requestJsonAndCheck(
"PATCH",
f"{self.protection_url}/required_pull_request_reviews",
@@ -494,17 +418,16 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
f"{self.protection_url}/required_pull_request_reviews",
)
- def get_admin_enforcement(self):
+ def get_admin_enforcement(self) -> bool:
"""
:calls: `GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins `_
- :rtype: bool
"""
headers, data = self._requester.requestJsonAndCheck(
"GET", f"{self.protection_url}/enforce_admins"
)
return data["enabled"]
- def set_admin_enforcement(self):
+ def set_admin_enforcement(self) -> None:
"""
:calls: `POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins `_
"""
@@ -512,7 +435,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
"POST", f"{self.protection_url}/enforce_admins"
)
- def remove_admin_enforcement(self):
+ def remove_admin_enforcement(self) -> None:
"""
:calls: `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins `_
"""
@@ -520,10 +443,9 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
"DELETE", f"{self.protection_url}/enforce_admins"
)
- def get_user_push_restrictions(self):
+ def get_user_push_restrictions(self) -> PaginatedList[NamedUser]:
"""
:calls: `GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users `_
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.NamedUser.NamedUser`
"""
return github.PaginatedList.PaginatedList(
github.NamedUser.NamedUser,
@@ -532,10 +454,9 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
None,
)
- def get_team_push_restrictions(self):
+ def get_team_push_restrictions(self) -> PaginatedList[Team]:
"""
:calls: `GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams `_
- :rtype: :class:`github.PaginatedList.PaginatedList` of :class:`github.Team.Team`
"""
return github.PaginatedList.PaginatedList(
github.Team.Team,
@@ -544,7 +465,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
None,
)
- def add_user_push_restrictions(self, *users):
+ def add_user_push_restrictions(self, *users: str) -> None:
"""
:calls: `POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users `_
:users: list of strings (user names)
@@ -555,7 +476,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
"POST", f"{self.protection_url}/restrictions/users", input=users
)
- def replace_user_push_restrictions(self, *users):
+ def replace_user_push_restrictions(self, *users: str) -> None:
"""
:calls: `PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users `_
:users: list of strings (user names)
@@ -566,7 +487,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
"PUT", f"{self.protection_url}/restrictions/users", input=users
)
- def remove_user_push_restrictions(self, *users):
+ def remove_user_push_restrictions(self, *users: str) -> None:
"""
:calls: `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users `_
:users: list of strings (user names)
@@ -577,7 +498,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
"DELETE", f"{self.protection_url}/restrictions/users", input=users
)
- def add_team_push_restrictions(self, *teams):
+ def add_team_push_restrictions(self, *teams: str) -> None:
"""
:calls: `POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams `_
:teams: list of strings (team slugs)
@@ -588,7 +509,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
"POST", f"{self.protection_url}/restrictions/teams", input=teams
)
- def replace_team_push_restrictions(self, *teams):
+ def replace_team_push_restrictions(self, *teams: str) -> None:
"""
:calls: `PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams `_
:teams: list of strings (team slugs)
@@ -599,7 +520,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
"PUT", f"{self.protection_url}/restrictions/teams", input=teams
)
- def remove_team_push_restrictions(self, *teams):
+ def remove_team_push_restrictions(self, *teams: str) -> None:
"""
:calls: `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams `_
:teams: list of strings (team slugs)
@@ -610,7 +531,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
"DELETE", f"{self.protection_url}/restrictions/teams", input=teams
)
- def remove_push_restrictions(self):
+ def remove_push_restrictions(self) -> None:
"""
:calls: `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions `_
"""
@@ -618,7 +539,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
"DELETE", f"{self.protection_url}/restrictions"
)
- def get_required_signatures(self):
+ def get_required_signatures(self) -> bool:
"""
:calls: `GET /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures `_
"""
@@ -629,7 +550,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
)
return data["enabled"]
- def add_required_signatures(self):
+ def add_required_signatures(self) -> None:
"""
:calls: `POST /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures `_
"""
@@ -639,7 +560,7 @@ class Branch(github.GithubObject.NonCompletableGithubObject):
headers={"Accept": Consts.signaturesProtectedBranchesPreview},
)
- def remove_required_signatures(self):
+ def remove_required_signatures(self) -> None:
"""
:calls: `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures `_
"""
diff --git a/github/Branch.pyi b/github/Branch.pyi
deleted file mode 100644
index 2c086776..00000000
--- a/github/Branch.pyi
+++ /dev/null
@@ -1,77 +0,0 @@
-from typing import Any, Dict, List, Union
-
-from github.BranchProtection import BranchProtection
-from github.Commit import Commit
-from github.GithubObject import NonCompletableGithubObject, _NotSetType
-from github.NamedUser import NamedUser
-from github.PaginatedList import PaginatedList
-from github.RequiredPullRequestReviews import RequiredPullRequestReviews
-from github.RequiredStatusChecks import RequiredStatusChecks
-from github.Team import Team
-
-class Branch(NonCompletableGithubObject):
- def __repr__(self) -> str: ...
- def _initAttributes(self) -> None: ...
- def _useAttributes(self, attributes: Dict[str, Any]) -> None: ...
- def add_required_signatures(self) -> None: ...
- @property
- def commit(self) -> Commit: ...
- def edit_protection(
- self,
- strict: Union[bool, _NotSetType] = ...,
- contexts: Union[List[str], _NotSetType] = ...,
- enforce_admins: Union[bool, _NotSetType] = ...,
- dismissal_users: Union[_NotSetType, List[str]] = ...,
- dismissal_teams: Union[_NotSetType, List[str]] = ...,
- dismissal_apps: Union[_NotSetType, List[str]] = ...,
- dismiss_stale_reviews: Union[bool, _NotSetType] = ...,
- require_code_owner_reviews: Union[bool, _NotSetType] = ...,
- required_approving_review_count: Union[int, _NotSetType] = ...,
- user_push_restrictions: Union[_NotSetType, List[str]] = ...,
- team_push_restrictions: Union[_NotSetType, List[str]] = ...,
- app_push_restrictions: Union[_NotSetType, List[str]] = ...,
- required_linear_history: Union[bool, _NotSetType] = ...,
- allow_force_pushes: Union[bool, _NotSetType] = ...,
- required_conversation_resolution: Union[bool, _NotSetType] = ...,
- lock_branch: Union[bool, _NotSetType] = ...,
- allow_fork_syncing: Union[bool, _NotSetType] = ...,
- users_bypass_pull_request_allowances: Union[_NotSetType, List[str]] = ...,
- teams_bypass_pull_request_allowances: Union[_NotSetType, List[str]] = ...,
- apps_bypass_pull_request_allowances: Union[_NotSetType, List[str]] = ...,
- ) -> None: ...
- def edit_required_pull_request_reviews(
- self,
- dismissal_users: Union[_NotSetType, List[str]] = ...,
- dismissal_teams: Union[_NotSetType, List[str]] = ...,
- dismissal_apps: Union[_NotSetType, List[str]] = ...,
- dismiss_stale_reviews: Union[bool, _NotSetType] = ...,
- require_code_owner_reviews: Union[_NotSetType, bool] = ...,
- required_approving_review_count: Union[int, _NotSetType] = ...,
- ) -> None: ...
- def edit_required_status_checks(
- self,
- strict: Union[_NotSetType, bool] = ...,
- contexts: Union[List[str], _NotSetType] = ...,
- ) -> None: ...
- def edit_team_push_restrictions(self, *teams: str) -> None: ...
- def edit_user_push_restrictions(self, *users: str) -> None: ...
- def get_admin_enforcement(self) -> bool: ...
- def get_protection(self) -> BranchProtection: ...
- def get_required_pull_request_reviews(self) -> RequiredPullRequestReviews: ...
- def get_required_signatures(self) -> bool: ...
- def get_required_status_checks(self) -> RequiredStatusChecks: ...
- def get_team_push_restrictions(self) -> PaginatedList[Team]: ...
- def get_user_push_restrictions(self) -> PaginatedList[NamedUser]: ...
- @property
- def name(self) -> str: ...
- @property
- def protected(self) -> bool: ...
- @property
- def protection_url(self) -> str: ...
- def remove_admin_enforcement(self) -> None: ...
- def remove_protection(self) -> None: ...
- def remove_push_restrictions(self) -> None: ...
- def remove_required_pull_request_reviews(self) -> None: ...
- def remove_required_signatures(self) -> None: ...
- def remove_required_status_checks(self) -> None: ...
- def set_admin_enforcement(self) -> None: ...
diff --git a/github/GithubObject.py b/github/GithubObject.py
index dadad2f9..6e59d48f 100644
--- a/github/GithubObject.py
+++ b/github/GithubObject.py
@@ -54,6 +54,7 @@ from typing import (
)
from dateutil import parser
+from typing_extensions import TypeGuard
from . import Consts
from .GithubException import BadAttributeException, IncompletableObject
@@ -92,6 +93,26 @@ NotSet = _NotSetType()
Opt = Union[T, _NotSetType]
+def is_defined(v: Union[T, _NotSetType]) -> TypeGuard[T]:
+ return not isinstance(v, _NotSetType)
+
+
+def is_undefined(v: Any) -> TypeGuard[_NotSetType]:
+ return isinstance(v, _NotSetType)
+
+
+def is_optional(v, type: Type[T]) -> TypeGuard[Opt[T]]:
+ return isinstance(v, _NotSetType) or isinstance(v, type)
+
+
+def is_optional_list(v, type: Type[T]) -> TypeGuard[Opt[List[T]]]:
+ return (
+ isinstance(v, _NotSetType)
+ or isinstance(v, list)
+ and all(isinstance(element, type) for element in v)
+ )
+
+
class _ValuedAttribute(Attribute, Generic[T]):
def __init__(self, value: T):
self._value = value
diff --git a/setup.py b/setup.py
index 137401f6..e6c4b75c 100755
--- a/setup.py
+++ b/setup.py
@@ -116,6 +116,7 @@ if __name__ == "__main__":
"pynacl>=1.4.0",
"requests>=2.14.0",
"python-dateutil",
+ "typing-extensions>=4.0.0",
],
# can be removed, still here to avoid breaking user code
extras_require={"integrations": []},