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()

```

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",
         ),
     )

{"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"}]}