prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Allow update of protected branches
  In gitlab 15.6 gitlab finally added api support to update protected branch settings, so ProjectProtectedBranch should be updated accordingly
  
  https://gitlab.com/gitlab-org/gitlab/-/issues/20229/
  
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `gitlab/v4/objects/branches.py`
  Content:
  ```
  1 from typing import Any, cast, Union
  2 
  3 from gitlab.base import RESTManager, RESTObject
  4 from gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin
  5 from gitlab.types import RequiredOptional
  6 
  7 __all__ = [
  8     "ProjectBranch",
  9     "ProjectBranchManager",
  10     "ProjectProtectedBranch",
  11     "ProjectProtectedBranchManager",
  12 ]
  13 
  14 
  15 class ProjectBranch(ObjectDeleteMixin, RESTObject):
  16     _id_attr = "name"
  17 
  18 
  19 class ProjectBranchManager(NoUpdateMixin, RESTManager):
  20     _path = "/projects/{project_id}/repository/branches"
  21     _obj_cls = ProjectBranch
  22     _from_parent_attrs = {"project_id": "id"}
  23     _create_attrs = RequiredOptional(required=("branch", "ref"))
  24 
  25     def get(
  26         self, id: Union[str, int], lazy: bool = False, **kwargs: Any
  27     ) -> ProjectBranch:
  28         return cast(ProjectBranch, super().get(id=id, lazy=lazy, **kwargs))
  29 
  30 
  31 class ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):
  32     _id_attr = "name"
  33 
  34 
  35 class ProjectProtectedBranchManager(NoUpdateMixin, RESTManager):
  36     _path = "/projects/{project_id}/protected_branches"
  37     _obj_cls = ProjectProtectedBranch
  38     _from_parent_attrs = {"project_id": "id"}
  39     _create_attrs = RequiredOptional(
  40         required=("name",),
  41         optional=(
  42             "push_access_level",
  43             "merge_access_level",
  44             "unprotect_access_level",
  45             "allow_force_push",
  46             "allowed_to_push",
  47             "allowed_to_merge",
  48             "allowed_to_unprotect",
  49             "code_owner_approval_required",
  50         ),
  51     )
  52 
  53     def get(
  54         self, id: Union[str, int], lazy: bool = False, **kwargs: Any
  55     ) -> ProjectProtectedBranch:
  56         return cast(ProjectProtectedBranch, super().get(id=id, lazy=lazy, **kwargs))
  57
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/gitlab/v4/objects/branches.py b/gitlab/v4/objects/branches.py
  --- a/gitlab/v4/objects/branches.py
  +++ b/gitlab/v4/objects/branches.py
  @@ -1,7 +1,13 @@
   from typing import Any, cast, Union
   
   from gitlab.base import RESTManager, RESTObject
  -from gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin
  +from gitlab.mixins import (
  +    CRUDMixin,
  +    NoUpdateMixin,
  +    ObjectDeleteMixin,
  +    SaveMixin,
  +    UpdateMethod,
  +)
   from gitlab.types import RequiredOptional
   
   __all__ = [
  @@ -28,11 +34,11 @@
           return cast(ProjectBranch, super().get(id=id, lazy=lazy, **kwargs))
   
   
  -class ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):
  +class ProjectProtectedBranch(SaveMixin, ObjectDeleteMixin, RESTObject):
       _id_attr = "name"
   
   
  -class ProjectProtectedBranchManager(NoUpdateMixin, RESTManager):
  +class ProjectProtectedBranchManager(CRUDMixin, RESTManager):
       _path = "/projects/{project_id}/protected_branches"
       _obj_cls = ProjectProtectedBranch
       _from_parent_attrs = {"project_id": "id"}
  @@ -49,6 +55,7 @@
               "code_owner_approval_required",
           ),
       )
  +    _update_method = UpdateMethod.PATCH
   
       def get(
           self, id: Union[str, int], lazy: bool = False, **kwargs: Any
  
verification_info: {"golden_diff": "diff --git a/gitlab/v4/objects/branches.py b/gitlab/v4/objects/branches.py\n--- a/gitlab/v4/objects/branches.py\n+++ b/gitlab/v4/objects/branches.py\n@@ -1,7 +1,13 @@\n from typing import Any, cast, Union\n \n from gitlab.base import RESTManager, RESTObject\n-from gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin\n+from gitlab.mixins import (\n+    CRUDMixin,\n+    NoUpdateMixin,\n+    ObjectDeleteMixin,\n+    SaveMixin,\n+    UpdateMethod,\n+)\n from gitlab.types import RequiredOptional\n \n __all__ = [\n@@ -28,11 +34,11 @@\n         return cast(ProjectBranch, super().get(id=id, lazy=lazy, **kwargs))\n \n \n-class ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):\n+class ProjectProtectedBranch(SaveMixin, ObjectDeleteMixin, RESTObject):\n     _id_attr = \"name\"\n \n \n-class ProjectProtectedBranchManager(NoUpdateMixin, RESTManager):\n+class ProjectProtectedBranchManager(CRUDMixin, RESTManager):\n     _path = \"/projects/{project_id}/protected_branches\"\n     _obj_cls = ProjectProtectedBranch\n     _from_parent_attrs = {\"project_id\": \"id\"}\n@@ -49,6 +55,7 @@\n             \"code_owner_approval_required\",\n         ),\n     )\n+    _update_method = UpdateMethod.PATCH\n \n     def get(\n         self, id: Union[str, int], lazy: bool = False, **kwargs: Any\n", "issue": "Allow update of protected branches\nIn gitlab 15.6 gitlab finally added api support to update protected branch settings, so ProjectProtectedBranch should be updated accordingly\r\n\r\nhttps://gitlab.com/gitlab-org/gitlab/-/issues/20229/\r\n\r\n\r\n\n", "before_files": [{"content": "from typing import Any, cast, Union\n\nfrom gitlab.base import RESTManager, RESTObject\nfrom gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin\nfrom gitlab.types import RequiredOptional\n\n__all__ = [\n    \"ProjectBranch\",\n    \"ProjectBranchManager\",\n    \"ProjectProtectedBranch\",\n    \"ProjectProtectedBranchManager\",\n]\n\n\nclass ProjectBranch(ObjectDeleteMixin, RESTObject):\n    _id_attr = \"name\"\n\n\nclass ProjectBranchManager(NoUpdateMixin, RESTManager):\n    _path = \"/projects/{project_id}/repository/branches\"\n    _obj_cls = ProjectBranch\n    _from_parent_attrs = {\"project_id\": \"id\"}\n    _create_attrs = RequiredOptional(required=(\"branch\", \"ref\"))\n\n    def get(\n        self, id: Union[str, int], lazy: bool = False, **kwargs: Any\n    ) -> ProjectBranch:\n        return cast(ProjectBranch, super().get(id=id, lazy=lazy, **kwargs))\n\n\nclass ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):\n    _id_attr = \"name\"\n\n\nclass ProjectProtectedBranchManager(NoUpdateMixin, RESTManager):\n    _path = \"/projects/{project_id}/protected_branches\"\n    _obj_cls = ProjectProtectedBranch\n    _from_parent_attrs = {\"project_id\": \"id\"}\n    _create_attrs = RequiredOptional(\n        required=(\"name\",),\n        optional=(\n            \"push_access_level\",\n            \"merge_access_level\",\n            \"unprotect_access_level\",\n            \"allow_force_push\",\n            \"allowed_to_push\",\n            \"allowed_to_merge\",\n            \"allowed_to_unprotect\",\n            \"code_owner_approval_required\",\n        ),\n    )\n\n    def get(\n        self, id: Union[str, int], lazy: bool = False, **kwargs: Any\n    ) -> ProjectProtectedBranch:\n        return cast(ProjectProtectedBranch, super().get(id=id, lazy=lazy, **kwargs))\n", "path": "gitlab/v4/objects/branches.py"}], "after_files": [{"content": "from typing import Any, cast, Union\n\nfrom gitlab.base import RESTManager, RESTObject\nfrom gitlab.mixins import (\n    CRUDMixin,\n    NoUpdateMixin,\n    ObjectDeleteMixin,\n    SaveMixin,\n    UpdateMethod,\n)\nfrom gitlab.types import RequiredOptional\n\n__all__ = [\n    \"ProjectBranch\",\n    \"ProjectBranchManager\",\n    \"ProjectProtectedBranch\",\n    \"ProjectProtectedBranchManager\",\n]\n\n\nclass ProjectBranch(ObjectDeleteMixin, RESTObject):\n    _id_attr = \"name\"\n\n\nclass ProjectBranchManager(NoUpdateMixin, RESTManager):\n    _path = \"/projects/{project_id}/repository/branches\"\n    _obj_cls = ProjectBranch\n    _from_parent_attrs = {\"project_id\": \"id\"}\n    _create_attrs = RequiredOptional(required=(\"branch\", \"ref\"))\n\n    def get(\n        self, id: Union[str, int], lazy: bool = False, **kwargs: Any\n    ) -> ProjectBranch:\n        return cast(ProjectBranch, super().get(id=id, lazy=lazy, **kwargs))\n\n\nclass ProjectProtectedBranch(SaveMixin, ObjectDeleteMixin, RESTObject):\n    _id_attr = \"name\"\n\n\nclass ProjectProtectedBranchManager(CRUDMixin, RESTManager):\n    _path = \"/projects/{project_id}/protected_branches\"\n    _obj_cls = ProjectProtectedBranch\n    _from_parent_attrs = {\"project_id\": \"id\"}\n    _create_attrs = RequiredOptional(\n        required=(\"name\",),\n        optional=(\n            \"push_access_level\",\n            \"merge_access_level\",\n            \"unprotect_access_level\",\n            \"allow_force_push\",\n            \"allowed_to_push\",\n            \"allowed_to_merge\",\n            \"allowed_to_unprotect\",\n            \"code_owner_approval_required\",\n        ),\n    )\n    _update_method = UpdateMethod.PATCH\n\n    def get(\n        self, id: Union[str, int], lazy: bool = False, **kwargs: Any\n    ) -> ProjectProtectedBranch:\n        return cast(ProjectProtectedBranch, super().get(id=id, lazy=lazy, **kwargs))\n", "path": "gitlab/v4/objects/branches.py"}]}