Repository: PyGithub/PyGithub

Issue:
issue in branch protection rules
Under branch protection rule GitHub provide   **Require conversation resolution before merging** .
But I am not able to access it through parameters of    **.edit_protection()**  (a method of branch object), although I can access other branch protection rules.



Discussion:
Maybe #2211 would help you?
There are a couple of parameters missing from edit_protection

required_linear_history
allow_force_pushes
allow_deletions
block_creations
required_conversation_resolution

This is from https://docs.github.com/en/rest/branches/branch-protection#update-branch-protection

Resolving patch:
diff --git a/github/Branch.py b/github/Branch.py
--- a/github/Branch.py
+++ b/github/Branch.py
@@ -149,6 +149,8 @@ def edit_protection(
         teams_bypass_pull_request_allowances: Opt[list[str]] = NotSet,
         apps_bypass_pull_request_allowances: Opt[list[str]] = NotSet,
         block_creations: Opt[bool] = NotSet,
+        require_last_push_approval: Opt[bool] = NotSet,
+        allow_deletions: Opt[bool] = NotSet,
     ) -> BranchProtection:
         """
         :calls: `PUT /repos/{owner}/{repo}/branches/{branch}/protection <https://docs.github.com/en/rest/reference/repos#get-branch-protection>`_
@@ -174,6 +176,8 @@ def edit_protection(
         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
+        assert is_optional(require_last_push_approval, bool), require_last_push_approval
+        assert is_optional(allow_deletions, bool), allow_deletions
 
         post_parameters: dict[str, Any] = {}
         if is_defined(strict) or is_defined(contexts):
@@ -203,6 +207,7 @@ def edit_protection(
             or is_defined(users_bypass_pull_request_allowances)
             or is_defined(teams_bypass_pull_request_allowances)
             or is_defined(apps_bypass_pull_request_allowances)
+            or is_defined(require_last_push_approval)
         ):
             post_parameters["required_pull_request_reviews"] = {}
             if is_defined(dismiss_stale_reviews):
@@ -215,6 +220,10 @@ def edit_protection(
                 post_parameters["required_pull_request_reviews"][
                     "required_approving_review_count"
                 ] = required_approving_review_count
+            if is_defined(require_last_push_approval):
+                post_parameters["required_pull_request_reviews"][
+                    "require_last_push_approval"
+                ] = require_last_push_approval
 
             dismissal_restrictions = {}
             if is_defined(dismissal_users):
@@ -283,6 +292,10 @@ def edit_protection(
             post_parameters["block_creations"] = block_creations
         else:
             post_parameters["block_creations"] = None
+        if is_defined(allow_deletions):
+            post_parameters["allow_deletions"] = allow_deletions
+        else:
+            post_parameters["allow_deletions"] = None
 
         headers, data = self._requester.requestJsonAndCheck(
             "PUT",
@@ -360,6 +373,7 @@ def edit_required_pull_request_reviews(
         dismiss_stale_reviews: Opt[bool] = NotSet,
         require_code_owner_reviews: Opt[bool] = NotSet,
         required_approving_review_count: Opt[int] = NotSet,
+        require_last_push_approval: Opt[bool] = NotSet,
     ) -> RequiredStatusChecks:
         """
         :calls: `PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews <https://docs.github.com/en/rest/reference/repos#branches>`_
@@ -369,12 +383,14 @@ def edit_required_pull_request_reviews(
         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(require_last_push_approval, bool), require_last_push_approval
 
         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,
+                "require_last_push_approval": require_last_push_approval,
             }
         )
 
@@ -546,3 +562,22 @@ def remove_required_signatures(self) -> None:
             f"{self.protection_url}/required_signatures",
             headers={"Accept": Consts.signaturesProtectedBranchesPreview},
         )
+
+    def get_allow_deletions(self) -> bool:
+        """
+        :calls: `GET /repos/{owner}/{repo}/branches/{branch}/protection/allow_deletions <https://docs.github.com/en/rest/reference/repos#branches>`_
+        """
+        headers, data = self._requester.requestJsonAndCheck("GET", f"{self.protection_url}/allow_deletions")
+        return data["enabled"]
+
+    def set_allow_deletions(self) -> None:
+        """
+        :calls: `POST /repos/{owner}/{repo}/branches/{branch}/protection/allow_deletions <https://docs.github.com/en/rest/reference/repos#branches>`_
+        """
+        headers, data = self._requester.requestJsonAndCheck("POST", f"{self.protection_url}/allow_deletions")
+
+    def remove_allow_deletions(self) -> None:
+        """
+        :calls: `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/allow_deletions <https://docs.github.com/en/rest/reference/repos#branches>`_
+        """
+        headers, data = self._requester.requestJsonAndCheck("DELETE", f"{self.protection_url}/allow_deletions")
diff --git a/github/BranchProtection.py b/github/BranchProtection.py
--- a/github/BranchProtection.py
+++ b/github/BranchProtection.py
@@ -56,6 +56,11 @@ def __repr__(self) -> str:
 
     def _initAttributes(self) -> None:
         self._url: Attribute[str] = NotSet
+        self._allow_deletions: Attribute[bool] = NotSet
+        self._allow_force_pushes: Attribute[bool] = NotSet
+        self._allow_fork_syncing: Attribute[bool] = NotSet
+        self._lock_branch: Attribute[bool] = NotSet
+        self._required_conversation_resolution: Attribute[bool] = NotSet
         self._required_status_checks: Attribute[RequiredStatusChecks] = NotSet
         self._enforce_admins: Attribute[bool] = NotSet
         self._required_linear_history: Attribute[bool] = github.GithubObject.NotSet
@@ -63,6 +68,31 @@ def _initAttributes(self) -> None:
         self._user_push_restrictions: Opt[str] = NotSet
         self._team_push_restrictions: Opt[str] = NotSet
 
+    @property
+    def allow_deletions(self) -> bool:
+        self._completeIfNotSet(self._allow_deletions)
+        return self._allow_deletions.value
+
+    @property
+    def allow_force_pushes(self) -> bool:
+        self._completeIfNotSet(self._allow_force_pushes)
+        return self._allow_force_pushes.value
+
+    @property
+    def allow_fork_syncing(self) -> bool:
+        self._completeIfNotSet(self._allow_fork_syncing)
+        return self._allow_fork_syncing.value
+
+    @property
+    def lock_branch(self) -> bool:
+        self._completeIfNotSet(self._lock_branch)
+        return self._lock_branch.value
+
+    @property
+    def required_conversation_resolution(self) -> bool:
+        self._completeIfNotSet(self._required_conversation_resolution)
+        return self._required_conversation_resolution.value
+
     @property
     def url(self) -> str:
         self._completeIfNotSet(self._url)
@@ -104,6 +134,18 @@ def get_team_push_restrictions(self) -> PaginatedList[Team] | None:
         return github.PaginatedList.PaginatedList(github.Team.Team, self._requester, self._team_push_restrictions, None)
 
     def _useAttributes(self, attributes: dict[str, Any]) -> None:
+        if "allow_deletions" in attributes:  # pragma no branch
+            self._allow_deletions = self._makeBoolAttribute(attributes["allow_deletions"]["enabled"])
+        if "allow_force_pushes" in attributes:  # pragma no branch
+            self._allow_force_pushes = self._makeBoolAttribute(attributes["allow_force_pushes"]["enabled"])
+        if "allow_fork_syncing" in attributes:  # pragma no branch
+            self._allow_fork_syncing = self._makeBoolAttribute(attributes["allow_fork_syncing"]["enabled"])
+        if "lock_branch" in attributes:  # pragma no branch
+            self._lock_branch = self._makeBoolAttribute(attributes["lock_branch"]["enabled"])
+        if "required_conversation_resolution" in attributes:  # pragma no branch
+            self._required_conversation_resolution = self._makeBoolAttribute(
+                attributes["required_conversation_resolution"]["enabled"]
+            )
         if "url" in attributes:  # pragma no branch
             self._url = self._makeStringAttribute(attributes["url"])
         if "required_status_checks" in attributes:  # pragma no branch
diff --git a/github/RequiredPullRequestReviews.py b/github/RequiredPullRequestReviews.py
--- a/github/RequiredPullRequestReviews.py
+++ b/github/RequiredPullRequestReviews.py
@@ -62,6 +62,7 @@ def _initAttributes(self) -> None:
         self._required_approving_review_count: Attribute[int] = NotSet
         self._users: Attribute[list[NamedUser]] = NotSet
         self._teams: Attribute[list[Team]] = NotSet
+        self._require_last_push_approval: Attribute[bool] = NotSet
 
     def __repr__(self) -> str:
         return self.get__repr__(
@@ -69,6 +70,7 @@ def __repr__(self) -> str:
                 "url": self._url.value,
                 "dismiss_stale_reviews": self._dismiss_stale_reviews.value,
                 "require_code_owner_reviews": self._require_code_owner_reviews.value,
+                "require_last_push_approval": self._require_last_push_approval.value,
             }
         )
 
@@ -87,6 +89,11 @@ def required_approving_review_count(self) -> int:
         self._completeIfNotSet(self._required_approving_review_count)
         return self._required_approving_review_count.value
 
+    @property
+    def require_last_push_approval(self) -> bool:
+        self._completeIfNotSet(self._require_last_push_approval)
+        return self._require_last_push_approval.value
+
     @property
     def url(self) -> str:
         self._completeIfNotSet(self._url)
@@ -121,5 +128,7 @@ def _useAttributes(self, attributes: dict[str, Any]) -> None:
             self._required_approving_review_count = self._makeIntAttribute(
                 attributes["required_approving_review_count"]
             )
+        if "require_last_push_approval" in attributes:  # pragma no branch
+            self._require_last_push_approval = self._makeBoolAttribute(attributes["require_last_push_approval"])
         if "url" in attributes:  # pragma no branch
             self._url = self._makeStringAttribute(attributes["url"])


Test patch:
diff --git a/tests/Branch.py b/tests/Branch.py
--- a/tests/Branch.py
+++ b/tests/Branch.py
@@ -64,18 +64,21 @@ def testEditProtection(self):
             strict=True,
             require_code_owner_reviews=True,
             required_approving_review_count=2,
+            require_last_push_approval=True,
         )
         branch_protection = self.protected_branch.get_protection()
         self.assertTrue(branch_protection.required_status_checks.strict)
         self.assertEqual(branch_protection.required_status_checks.contexts, [])
         self.assertTrue(branch_protection.enforce_admins)
         self.assertFalse(branch_protection.required_linear_history)
+        self.assertFalse(branch_protection.allow_deletions)
         self.assertFalse(branch_protection.required_pull_request_reviews.dismiss_stale_reviews)
         self.assertTrue(branch_protection.required_pull_request_reviews.require_code_owner_reviews)
         self.assertEqual(
             branch_protection.required_pull_request_reviews.required_approving_review_count,
             2,
         )
+        self.assertTrue(branch_protection.required_pull_request_reviews.require_last_push_approval)
 
     def testEditProtectionDismissalUsersWithUserOwnedBranch(self):
         with self.assertRaises(github.GithubException) as raisedexp:
@@ -160,7 +163,8 @@ def testRemoveRequiredStatusChecks(self):
 
     def testEditRequiredPullRequestReviews(self):
         self.protected_branch.edit_required_pull_request_reviews(
-            dismiss_stale_reviews=True, required_approving_review_count=2
+            dismiss_stale_reviews=True,
+            required_approving_review_count=2,
         )
         required_pull_request_reviews = self.protected_branch.get_required_pull_request_reviews()
         self.assertTrue(required_pull_request_reviews.dismiss_stale_reviews)
@@ -197,6 +201,7 @@ def testRemoveRequiredPullRequestReviews(self):
         self.assertFalse(required_pull_request_reviews.dismiss_stale_reviews)
         self.assertFalse(required_pull_request_reviews.require_code_owner_reviews)
         self.assertEqual(required_pull_request_reviews.required_approving_review_count, 1)
+        self.assertFalse(required_pull_request_reviews.require_last_push_approval)
 
     def testAdminEnforcement(self):
         self.protected_branch.remove_admin_enforcement()
@@ -204,6 +209,12 @@ def testAdminEnforcement(self):
         self.protected_branch.set_admin_enforcement()
         self.assertTrue(self.protected_branch.get_admin_enforcement())
 
+    def testAllowDeletions(self):
+        self.protected_branch.set_allow_deletions()
+        self.assertTrue(self.protected_branch.get_allow_deletions())
+        self.protected_branch.remove_allow_deletions()
+        self.assertFalse(self.protected_branch.get_allow_deletions())
+
     def testAddUserPushRestrictions(self):
         self.organization_branch.add_user_push_restrictions("sfdye")
         self.assertListKeyEqual(
diff --git a/tests/BranchProtection.py b/tests/BranchProtection.py
--- a/tests/BranchProtection.py
+++ b/tests/BranchProtection.py
@@ -52,3 +52,8 @@ def testAttributes(self):
             self.branch_protection.__repr__(),
             'BranchProtection(url="https://api.github.com/repos/curvewise-forks/PyGithub/branches/master/protection")',
         )
+        self.assertFalse(self.branch_protection.allow_force_pushes)
+        self.assertFalse(self.branch_protection.allow_deletions)
+        self.assertFalse(self.branch_protection.required_conversation_resolution)
+        self.assertFalse(self.branch_protection.lock_branch)
+        self.assertFalse(self.branch_protection.allow_fork_syncing)
diff --git a/tests/ReplayData/Branch.testAllowDeletions.txt b/tests/ReplayData/Branch.testAllowDeletions.txt
new file mode 100644
--- /dev/null
+++ b/tests/ReplayData/Branch.testAllowDeletions.txt
@@ -0,0 +1,43 @@
+https
+POST
+api.github.com
+None
+/repos/jacquev6/PyGithub/branches/integrations/protection/allow_deletions
+{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
+None
+200
+[('strict-transport-security', 'max-age=31536000; includeSubdomains; preload'), ('vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('x-oauth-scopes', 'public_repo, repo:status'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('x-accepted-oauth-scopes', ''), ('etag', 'W/"5ebb2cbbb268262fba4eade23df2ed85"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('referrer-policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('status', '200 OK'), ('x-ratelimit-remaining', '4975'), ('x-github-media-type', 'github.v3; format=json'), ('access-control-expose-headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('transfer-encoding', 'chunked'), ('x-github-request-id', '935C:2DD6:186AD1F:1F9B1CD:5AF58E17'), ('date', 'Fri, 11 May 2018 12:35:51 GMT'), ('access-control-allow-origin', '*'), ('content-security-policy', "default-src 'none'"), ('content-encoding', 'gzip'), ('x-runtime-rack', '0.035550'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('x-frame-options', 'deny'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1526042267')]
+''
+
+https
+GET
+api.github.com
+None
+/repos/jacquev6/PyGithub/branches/integrations/protection/allow_deletions
+{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
+None
+200
+[('strict-transport-security', 'max-age=31536000; includeSubdomains; preload'), ('vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('x-oauth-scopes', 'public_repo, repo:status'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('x-accepted-oauth-scopes', ''), ('etag', 'W/"7e30c47ab395fea0aa2cb8f9c487c7be"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('referrer-policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('status', '200 OK'), ('x-ratelimit-remaining', '4998'), ('x-github-media-type', 'github.v3; format=json'), ('access-control-expose-headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('transfer-encoding', 'chunked'), ('x-github-request-id', '92CC:2DD0:1360C19:194AF93:5AF58EA4'), ('date', 'Fri, 11 May 2018 12:38:01 GMT'), ('access-control-allow-origin', '*'), ('content-security-policy', "default-src 'none'"), ('content-encoding', 'gzip'), ('x-runtime-rack', '0.038876'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('x-frame-options', 'deny'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1526045876')]
+{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/add-pr-review-request/protection/allow_deletions","enabled":true}
+
+https
+DELETE
+api.github.com
+None
+/repos/jacquev6/PyGithub/branches/integrations/protection/allow_deletions
+{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
+None
+204
+[('status', '204 No Content'), ('x-ratelimit-remaining', '4994'), ('content-length', '330'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"2dada6dafd332016bcdf06e42487e520"'), ('date', 'Thu, 10 May 2012 13:56:55 GMT'), ('content-type', 'application/json; charset=utf-8')]
+
+
+https
+GET
+api.github.com
+None
+/repos/jacquev6/PyGithub/branches/integrations/protection/allow_deletions
+{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
+None
+200
+[('strict-transport-security', 'max-age=31536000; includeSubdomains; preload'), ('vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('x-oauth-scopes', 'public_repo, repo:status'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('x-accepted-oauth-scopes', ''), ('etag', 'W/"5ebb2cbbb268262fba4eade23df2ed85"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('referrer-policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('status', '200 OK'), ('x-ratelimit-remaining', '4975'), ('x-github-media-type', 'github.v3; format=json'), ('access-control-expose-headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('transfer-encoding', 'chunked'), ('x-github-request-id', '935C:2DD6:186AD1F:1F9B1CD:5AF58E17'), ('date', 'Fri, 11 May 2018 12:35:41 GMT'), ('access-control-allow-origin', '*'), ('content-security-policy', "default-src 'none'"), ('content-encoding', 'gzip'), ('x-runtime-rack', '0.035550'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('x-frame-options', 'deny'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1526042267')]
+{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/add-pr-review-request/protection/allow_deletion","enabled":false}
diff --git a/tests/ReplayData/Branch.testEditProtection.txt b/tests/ReplayData/Branch.testEditProtection.txt
--- a/tests/ReplayData/Branch.testEditProtection.txt
+++ b/tests/ReplayData/Branch.testEditProtection.txt
@@ -4,7 +4,7 @@ api.github.com
 None
 /repos/jacquev6/PyGithub/branches/integrations/protection
 {'Authorization': 'Basic login_and_password_removed', 'Content-Type': 'application/json', 'User-Agent': 'PyGithub/Python', 'Accept': 'application/vnd.github.luke-cage-preview+json'}
-{"restrictions": null, "required_pull_request_reviews": {"require_code_owner_reviews": true, "required_approving_review_count": 2}, "required_status_checks": {"contexts": [], "strict": true}, "enforce_admins": null, "allow_force_pushes": null, "allow_fork_syncing": null, "lock_branch": null, "required_conversation_resolution": null, "required_linear_history": null, "block_creations": null }
+{"restrictions": null, "required_pull_request_reviews": {"require_code_owner_reviews": true, "required_approving_review_count": 2, "require_last_push_approval": true}, "required_status_checks": {"contexts": [], "strict": true}, "enforce_admins": null, "allow_force_pushes": null, "allow_fork_syncing": null, "lock_branch": null, "required_conversation_resolution": null, "required_linear_history": null, "block_creations": null, "allow_deletions": null }
 200
 [('status', '200 OK'), ('x-ratelimit-remaining', '4994'), ('content-length', '0'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"e0dc2dfc56971f4a36de1216356ea98b"'), ('date', 'Sat, 05 May 2018 06:05:54 GMT'), ('content-type', 'application/json; charset=utf-8')]
 ''
@@ -18,4 +18,4 @@ None
 None
 200
 [('status', '200 OK'), ('x-ratelimit-remaining', '4994'), ('content-length', '0'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"81ba94a48ad867b26d48c023ac584f43"'), ('date', 'Mon, 07 May 2018 13:42:41 GMT'), ('content-type', 'application/json; charset=utf-8')]
-{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection","required_pull_request_reviews":{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_pull_request_reviews","dismiss_stale_reviews":false,"require_code_owner_reviews":true,"required_approving_review_count":2},"required_status_checks":{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_status_checks","strict":true,"contexts":[],"contexts_url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_status_checks/contexts"},"enforce_admins":{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/enforce_admins","enabled":true}}
+{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection","required_pull_request_reviews":{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_pull_request_reviews","dismiss_stale_reviews":false,"require_code_owner_reviews":true,"required_approving_review_count":2,"require_last_push_approval":true},"required_status_checks":{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_status_checks","strict":true,"contexts":[],"contexts_url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_status_checks/contexts"},"enforce_admins":{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/enforce_admins","enabled":true}}
diff --git a/tests/ReplayData/Branch.testEditProtectionDismissalUsersWithUserOwnedBranch.txt b/tests/ReplayData/Branch.testEditProtectionDismissalUsersWithUserOwnedBranch.txt
--- a/tests/ReplayData/Branch.testEditProtectionDismissalUsersWithUserOwnedBranch.txt
+++ b/tests/ReplayData/Branch.testEditProtectionDismissalUsersWithUserOwnedBranch.txt
@@ -4,7 +4,7 @@ api.github.com
 None
 /repos/jacquev6/PyGithub/branches/integrations/protection
 {'Authorization': 'Basic login_and_password_removed', 'Content-Type': 'application/json', 'User-Agent': 'PyGithub/Python', 'Accept': 'application/vnd.github.luke-cage-preview+json'}
-{"restrictions": null, "required_pull_request_reviews": {"dismissal_restrictions": {"users": ["jacquev6"]}}, "required_status_checks": null, "enforce_admins": null, "allow_force_pushes": null, "allow_fork_syncing": null, "lock_branch": null, "required_conversation_resolution": null, "required_linear_history": null, "block_creations": null }
+{"restrictions": null, "required_pull_request_reviews": {"dismissal_restrictions": {"users": ["jacquev6"]}}, "required_status_checks": null, "enforce_admins": null, "allow_force_pushes": null, "allow_fork_syncing": null, "lock_branch": null, "required_conversation_resolution": null, "required_linear_history": null, "block_creations": null, "allow_deletions": null }
 422
 [('status', '422 Unprocessable Entity'), ('x-ratelimit-remaining', '4994'), ('content-length', '0'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"e0dc2dfc56971f4a36de1216356ea98b"'), ('date', 'Sun, 13 May 2018 10:42:14 GMT'), ('content-type', 'application/json; charset=utf-8')]
 {"documentation_url":"https://developer.github.com/v3/repos/branches/#update-branch-protection","message":"Validation Failed","errors":["Only organization repositories can have users and team restrictions"]}
diff --git a/tests/ReplayData/Branch.testEditProtectionPushRestrictionsAndDismissalUser.txt b/tests/ReplayData/Branch.testEditProtectionPushRestrictionsAndDismissalUser.txt
--- a/tests/ReplayData/Branch.testEditProtectionPushRestrictionsAndDismissalUser.txt
+++ b/tests/ReplayData/Branch.testEditProtectionPushRestrictionsAndDismissalUser.txt
@@ -4,7 +4,7 @@ api.github.com
 None
 /repos/PyGithub/PyGithub/branches/master/protection
 {'Authorization': 'Basic login_and_password_removed', 'Content-Type': 'application/json', 'User-Agent': 'PyGithub/Python', 'Accept': 'application/vnd.github.luke-cage-preview+json'}
-{"restrictions": {"apps": [], "teams": [], "users": ["jacquev6"]}, "required_pull_request_reviews": {"dismissal_restrictions": {"users": ["jacquev6"]}}, "required_status_checks": null, "enforce_admins": null, "allow_force_pushes": null, "allow_fork_syncing": null, "lock_branch": null, "required_conversation_resolution": null, "required_linear_history": null, "block_creations": null }
+{"restrictions": {"apps": [], "teams": [], "users": ["jacquev6"]}, "required_pull_request_reviews": {"dismissal_restrictions": {"users": ["jacquev6"]}}, "required_status_checks": null, "enforce_admins": null, "allow_force_pushes": null, "allow_fork_syncing": null, "lock_branch": null, "required_conversation_resolution": null, "required_linear_history": null, "block_creations": null, "allow_deletions": null }
 200
 [('status', '200 OK'), ('x-ratelimit-remaining', '4994'), ('content-length', '0'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"e0dc2dfc56971f4a36de1216356ea98b"'), ('date', 'Sun, 13 May 2018 13:21:24 GMT'), ('content-type', 'application/json; charset=utf-8')]
 ''
diff --git a/tests/ReplayData/Branch.testEditProtectionPushRestrictionsWithUserOwnedBranch.txt b/tests/ReplayData/Branch.testEditProtectionPushRestrictionsWithUserOwnedBranch.txt
--- a/tests/ReplayData/Branch.testEditProtectionPushRestrictionsWithUserOwnedBranch.txt
+++ b/tests/ReplayData/Branch.testEditProtectionPushRestrictionsWithUserOwnedBranch.txt
@@ -4,7 +4,7 @@ api.github.com
 None
 /repos/jacquev6/PyGithub/branches/integrations/protection
 {'Authorization': 'Basic login_and_password_removed', 'Content-Type': 'application/json', 'User-Agent': 'PyGithub/Python', 'Accept': 'application/vnd.github.luke-cage-preview+json'}
-{"restrictions": {"apps": [], "users": ["jacquev6"], "teams": []}, "required_pull_request_reviews": null, "required_status_checks": null, "enforce_admins": null, "allow_force_pushes": null, "allow_fork_syncing": null, "lock_branch": null, "required_conversation_resolution": null, "required_linear_history": null, "block_creations": null }
+{"restrictions": {"apps": [], "users": ["jacquev6"], "teams": []}, "required_pull_request_reviews": null, "required_status_checks": null, "enforce_admins": null, "allow_force_pushes": null, "allow_fork_syncing": null, "lock_branch": null, "required_conversation_resolution": null, "required_linear_history": null, "block_creations": null, "allow_deletions": null }
 422
 [('status', '422 Unprocessable Entity'), ('x-ratelimit-remaining', '4994'), ('content-length', '0'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"e0dc2dfc56971f4a36de1216356ea98b"'), ('date', 'Sat, 05 May 2018 06:05:54 GMT'), ('content-type', 'application/json; charset=utf-8')]
 {"documentation_url":"https://developer.github.com/v3/repos/branches/#update-branch-protection","message":"Validation Failed","errors":["Only organization repositories can have users and team restrictions"]}
diff --git a/tests/RequiredPullRequestReviews.py b/tests/RequiredPullRequestReviews.py
--- a/tests/RequiredPullRequestReviews.py
+++ b/tests/RequiredPullRequestReviews.py
@@ -48,6 +48,7 @@ def setUp(self):
     def testAttributes(self):
         self.assertTrue(self.required_pull_request_reviews.dismiss_stale_reviews)
         self.assertTrue(self.required_pull_request_reviews.require_code_owner_reviews)
+        self.assertIsNone(self.required_pull_request_reviews.require_last_push_approval)
         self.assertEqual(self.required_pull_request_reviews.required_approving_review_count, 3)
         self.assertEqual(
             self.required_pull_request_reviews.url,
@@ -57,7 +58,7 @@ def testAttributes(self):
         self.assertIs(self.required_pull_request_reviews.dismissal_teams, None)
         self.assertEqual(
             self.required_pull_request_reviews.__repr__(),
-            'RequiredPullRequestReviews(url="https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_pull_request_reviews", require_code_owner_reviews=True, dismiss_stale_reviews=True)',
+            'RequiredPullRequestReviews(url="https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_pull_request_reviews", require_last_push_approval=None, require_code_owner_reviews=True, dismiss_stale_reviews=True)',
         )
 
     def testOrganizationOwnedTeam(self):