prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Missing API code owner approval for protected branches
  ## Summary
  
  The branch manager is missing an attribute implementation of `code_owner_approval_required` as documented in [GitLab API documentation](https://docs.gitlab.com/ce/api/protected_branches.html#protect-repository-branches)
  
  ## Expected Behavior
  
  `ProjectProtectedBranchManager.code_owner_approval_required` should be implemented to mirror the API as documented:
  
  Attribute | Type | Required | Description
  -- | -- | -- | --
  code_owner_approval_required | boolean | no | Prevent pushes to this branch if it matches an item in the CODEOWNERS file. (defaults: false)
  
  ## Actual Behavior
  
  `code_owner_approval_required` is not available as attribute in `ProjectProtectedBranchManager`.
  
  
  --- 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 gitlab import cli
  2 from gitlab import exceptions as exc
  3 from gitlab.base import RequiredOptional, RESTManager, RESTObject
  4 from gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin
  5 
  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     @cli.register_custom_action(
  19         "ProjectBranch", tuple(), ("developers_can_push", "developers_can_merge")
  20     )
  21     @exc.on_http_error(exc.GitlabProtectError)
  22     def protect(self, developers_can_push=False, developers_can_merge=False, **kwargs):
  23         """Protect the branch.
  24 
  25         Args:
  26             developers_can_push (bool): Set to True if developers are allowed
  27                                         to push to the branch
  28             developers_can_merge (bool): Set to True if developers are allowed
  29                                          to merge to the branch
  30             **kwargs: Extra options to send to the server (e.g. sudo)
  31 
  32         Raises:
  33             GitlabAuthenticationError: If authentication is not correct
  34             GitlabProtectError: If the branch could not be protected
  35         """
  36         id = self.get_id().replace("/", "%2F")
  37         path = "%s/%s/protect" % (self.manager.path, id)
  38         post_data = {
  39             "developers_can_push": developers_can_push,
  40             "developers_can_merge": developers_can_merge,
  41         }
  42         self.manager.gitlab.http_put(path, post_data=post_data, **kwargs)
  43         self._attrs["protected"] = True
  44 
  45     @cli.register_custom_action("ProjectBranch")
  46     @exc.on_http_error(exc.GitlabProtectError)
  47     def unprotect(self, **kwargs):
  48         """Unprotect the branch.
  49 
  50         Args:
  51             **kwargs: Extra options to send to the server (e.g. sudo)
  52 
  53         Raises:
  54             GitlabAuthenticationError: If authentication is not correct
  55             GitlabProtectError: If the branch could not be unprotected
  56         """
  57         id = self.get_id().replace("/", "%2F")
  58         path = "%s/%s/unprotect" % (self.manager.path, id)
  59         self.manager.gitlab.http_put(path, **kwargs)
  60         self._attrs["protected"] = False
  61 
  62 
  63 class ProjectBranchManager(NoUpdateMixin, RESTManager):
  64     _path = "/projects/%(project_id)s/repository/branches"
  65     _obj_cls = ProjectBranch
  66     _from_parent_attrs = {"project_id": "id"}
  67     _create_attrs = RequiredOptional(required=("branch", "ref"))
  68 
  69 
  70 class ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):
  71     _id_attr = "name"
  72 
  73 
  74 class ProjectProtectedBranchManager(NoUpdateMixin, RESTManager):
  75     _path = "/projects/%(project_id)s/protected_branches"
  76     _obj_cls = ProjectProtectedBranch
  77     _from_parent_attrs = {"project_id": "id"}
  78     _create_attrs = RequiredOptional(
  79         required=("name",),
  80         optional=(
  81             "push_access_level",
  82             "merge_access_level",
  83             "unprotect_access_level",
  84             "allowed_to_push",
  85             "allowed_to_merge",
  86             "allowed_to_unprotect",
  87         ),
  88     )
  89
  ```
  --- 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
  @@ -84,5 +84,6 @@
               "allowed_to_push",
               "allowed_to_merge",
               "allowed_to_unprotect",
  +            "code_owner_approval_required",
           ),
       )
  
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@@ -84,5 +84,6 @@\n             \"allowed_to_push\",\n             \"allowed_to_merge\",\n             \"allowed_to_unprotect\",\n+            \"code_owner_approval_required\",\n         ),\n     )\n", "issue": "Missing API code owner approval for protected branches\n## Summary\r\n\r\nThe branch manager is missing an attribute implementation of `code_owner_approval_required` as documented in [GitLab API documentation](https://docs.gitlab.com/ce/api/protected_branches.html#protect-repository-branches)\r\n\r\n## Expected Behavior\r\n\r\n`ProjectProtectedBranchManager.code_owner_approval_required` should be implemented to mirror the API as documented:\r\n\r\nAttribute | Type | Required | Description\r\n-- | -- | -- | --\r\ncode_owner_approval_required | boolean | no | Prevent pushes to this branch if it matches an item in the\u00a0CODEOWNERS\u00a0file. (defaults: false)\r\n\r\n## Actual Behavior\r\n\r\n`code_owner_approval_required` is not available as attribute in `ProjectProtectedBranchManager`.\r\n\n", "before_files": [{"content": "from gitlab import cli\nfrom gitlab import exceptions as exc\nfrom gitlab.base import RequiredOptional, RESTManager, RESTObject\nfrom gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin\n\n\n__all__ = [\n    \"ProjectBranch\",\n    \"ProjectBranchManager\",\n    \"ProjectProtectedBranch\",\n    \"ProjectProtectedBranchManager\",\n]\n\n\nclass ProjectBranch(ObjectDeleteMixin, RESTObject):\n    _id_attr = \"name\"\n\n    @cli.register_custom_action(\n        \"ProjectBranch\", tuple(), (\"developers_can_push\", \"developers_can_merge\")\n    )\n    @exc.on_http_error(exc.GitlabProtectError)\n    def protect(self, developers_can_push=False, developers_can_merge=False, **kwargs):\n        \"\"\"Protect the branch.\n\n        Args:\n            developers_can_push (bool): Set to True if developers are allowed\n                                        to push to the branch\n            developers_can_merge (bool): Set to True if developers are allowed\n                                         to merge to the branch\n            **kwargs: Extra options to send to the server (e.g. sudo)\n\n        Raises:\n            GitlabAuthenticationError: If authentication is not correct\n            GitlabProtectError: If the branch could not be protected\n        \"\"\"\n        id = self.get_id().replace(\"/\", \"%2F\")\n        path = \"%s/%s/protect\" % (self.manager.path, id)\n        post_data = {\n            \"developers_can_push\": developers_can_push,\n            \"developers_can_merge\": developers_can_merge,\n        }\n        self.manager.gitlab.http_put(path, post_data=post_data, **kwargs)\n        self._attrs[\"protected\"] = True\n\n    @cli.register_custom_action(\"ProjectBranch\")\n    @exc.on_http_error(exc.GitlabProtectError)\n    def unprotect(self, **kwargs):\n        \"\"\"Unprotect the branch.\n\n        Args:\n            **kwargs: Extra options to send to the server (e.g. sudo)\n\n        Raises:\n            GitlabAuthenticationError: If authentication is not correct\n            GitlabProtectError: If the branch could not be unprotected\n        \"\"\"\n        id = self.get_id().replace(\"/\", \"%2F\")\n        path = \"%s/%s/unprotect\" % (self.manager.path, id)\n        self.manager.gitlab.http_put(path, **kwargs)\n        self._attrs[\"protected\"] = False\n\n\nclass ProjectBranchManager(NoUpdateMixin, RESTManager):\n    _path = \"/projects/%(project_id)s/repository/branches\"\n    _obj_cls = ProjectBranch\n    _from_parent_attrs = {\"project_id\": \"id\"}\n    _create_attrs = RequiredOptional(required=(\"branch\", \"ref\"))\n\n\nclass ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):\n    _id_attr = \"name\"\n\n\nclass ProjectProtectedBranchManager(NoUpdateMixin, RESTManager):\n    _path = \"/projects/%(project_id)s/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            \"allowed_to_push\",\n            \"allowed_to_merge\",\n            \"allowed_to_unprotect\",\n        ),\n    )\n", "path": "gitlab/v4/objects/branches.py"}], "after_files": [{"content": "from gitlab import cli\nfrom gitlab import exceptions as exc\nfrom gitlab.base import RequiredOptional, RESTManager, RESTObject\nfrom gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin\n\n\n__all__ = [\n    \"ProjectBranch\",\n    \"ProjectBranchManager\",\n    \"ProjectProtectedBranch\",\n    \"ProjectProtectedBranchManager\",\n]\n\n\nclass ProjectBranch(ObjectDeleteMixin, RESTObject):\n    _id_attr = \"name\"\n\n    @cli.register_custom_action(\n        \"ProjectBranch\", tuple(), (\"developers_can_push\", \"developers_can_merge\")\n    )\n    @exc.on_http_error(exc.GitlabProtectError)\n    def protect(self, developers_can_push=False, developers_can_merge=False, **kwargs):\n        \"\"\"Protect the branch.\n\n        Args:\n            developers_can_push (bool): Set to True if developers are allowed\n                                        to push to the branch\n            developers_can_merge (bool): Set to True if developers are allowed\n                                         to merge to the branch\n            **kwargs: Extra options to send to the server (e.g. sudo)\n\n        Raises:\n            GitlabAuthenticationError: If authentication is not correct\n            GitlabProtectError: If the branch could not be protected\n        \"\"\"\n        id = self.get_id().replace(\"/\", \"%2F\")\n        path = \"%s/%s/protect\" % (self.manager.path, id)\n        post_data = {\n            \"developers_can_push\": developers_can_push,\n            \"developers_can_merge\": developers_can_merge,\n        }\n        self.manager.gitlab.http_put(path, post_data=post_data, **kwargs)\n        self._attrs[\"protected\"] = True\n\n    @cli.register_custom_action(\"ProjectBranch\")\n    @exc.on_http_error(exc.GitlabProtectError)\n    def unprotect(self, **kwargs):\n        \"\"\"Unprotect the branch.\n\n        Args:\n            **kwargs: Extra options to send to the server (e.g. sudo)\n\n        Raises:\n            GitlabAuthenticationError: If authentication is not correct\n            GitlabProtectError: If the branch could not be unprotected\n        \"\"\"\n        id = self.get_id().replace(\"/\", \"%2F\")\n        path = \"%s/%s/unprotect\" % (self.manager.path, id)\n        self.manager.gitlab.http_put(path, **kwargs)\n        self._attrs[\"protected\"] = False\n\n\nclass ProjectBranchManager(NoUpdateMixin, RESTManager):\n    _path = \"/projects/%(project_id)s/repository/branches\"\n    _obj_cls = ProjectBranch\n    _from_parent_attrs = {\"project_id\": \"id\"}\n    _create_attrs = RequiredOptional(required=(\"branch\", \"ref\"))\n\n\nclass ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):\n    _id_attr = \"name\"\n\n\nclass ProjectProtectedBranchManager(NoUpdateMixin, RESTManager):\n    _path = \"/projects/%(project_id)s/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            \"allowed_to_push\",\n            \"allowed_to_merge\",\n            \"allowed_to_unprotect\",\n            \"code_owner_approval_required\",\n        ),\n    )\n", "path": "gitlab/v4/objects/branches.py"}]}