prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Deprecate tag.set_release_description and remove it from docs
  ## Description of the problem, including code/CLI snippet
  It seems that the code we use to create a release from a tag [here](https://github.com/python-gitlab/python-gitlab/blob/8753add72061ea01c508a42d16a27388b1d92677/gitlab/v4/objects/tags.py#L19) has been deprecated and removed
  
  We should update to use the new release API
  
  I'll try to investigate a little later tonight as it is blocking my team for some automated release tools.
  
  ## Expected Behavior
  - set_release_description() create or update a release
  
  ## Actual Behavior
  - 404 error
  
  ## Specifications
  
    - python-gitlab version: 2.8 (and 2.5)
    - API version you are using (v3/v4): v4
    - Gitlab server version (or gitlab.com): gitlab.com
  
  
  </issue>
  <code>
  [start of gitlab/v4/objects/releases.py]
  1 from gitlab.base import RequiredOptional, RESTManager, RESTObject
  2 from gitlab.mixins import CRUDMixin, NoUpdateMixin, ObjectDeleteMixin, SaveMixin
  3 
  4 __all__ = [
  5     "ProjectRelease",
  6     "ProjectReleaseManager",
  7     "ProjectReleaseLink",
  8     "ProjectReleaseLinkManager",
  9 ]
  10 
  11 
  12 class ProjectRelease(RESTObject):
  13     _id_attr = "tag_name"
  14     _managers = (("links", "ProjectReleaseLinkManager"),)
  15 
  16 
  17 class ProjectReleaseManager(NoUpdateMixin, RESTManager):
  18     _path = "/projects/%(project_id)s/releases"
  19     _obj_cls = ProjectRelease
  20     _from_parent_attrs = {"project_id": "id"}
  21     _create_attrs = RequiredOptional(
  22         required=("name", "tag_name", "description"), optional=("ref", "assets")
  23     )
  24 
  25 
  26 class ProjectReleaseLink(ObjectDeleteMixin, SaveMixin, RESTObject):
  27     pass
  28 
  29 
  30 class ProjectReleaseLinkManager(CRUDMixin, RESTManager):
  31     _path = "/projects/%(project_id)s/releases/%(tag_name)s/assets/links"
  32     _obj_cls = ProjectReleaseLink
  33     _from_parent_attrs = {"project_id": "project_id", "tag_name": "tag_name"}
  34     _create_attrs = RequiredOptional(
  35         required=("name", "url"), optional=("filepath", "link_type")
  36     )
  37     _update_attrs = RequiredOptional(optional=("name", "url", "filepath", "link_type"))
  38
  [end of gitlab/v4/objects/releases.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/gitlab/v4/objects/releases.py b/gitlab/v4/objects/releases.py
  --- a/gitlab/v4/objects/releases.py
  +++ b/gitlab/v4/objects/releases.py
  @@ -1,5 +1,5 @@
   from gitlab.base import RequiredOptional, RESTManager, RESTObject
  -from gitlab.mixins import CRUDMixin, NoUpdateMixin, ObjectDeleteMixin, SaveMixin
  +from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
   
   __all__ = [
       "ProjectRelease",
  @@ -9,18 +9,21 @@
   ]
   
   
  -class ProjectRelease(RESTObject):
  +class ProjectRelease(SaveMixin, RESTObject):
       _id_attr = "tag_name"
       _managers = (("links", "ProjectReleaseLinkManager"),)
   
   
  -class ProjectReleaseManager(NoUpdateMixin, RESTManager):
  +class ProjectReleaseManager(CRUDMixin, RESTManager):
       _path = "/projects/%(project_id)s/releases"
       _obj_cls = ProjectRelease
       _from_parent_attrs = {"project_id": "id"}
       _create_attrs = RequiredOptional(
           required=("name", "tag_name", "description"), optional=("ref", "assets")
       )
  +    _update_attrs = RequiredOptional(
  +        optional=("name", "description", "milestones", "released_at")
  +    )
   
   
   class ProjectReleaseLink(ObjectDeleteMixin, SaveMixin, RESTObject):
  
verification_info: {"golden_diff": "diff --git a/gitlab/v4/objects/releases.py b/gitlab/v4/objects/releases.py\n--- a/gitlab/v4/objects/releases.py\n+++ b/gitlab/v4/objects/releases.py\n@@ -1,5 +1,5 @@\n from gitlab.base import RequiredOptional, RESTManager, RESTObject\n-from gitlab.mixins import CRUDMixin, NoUpdateMixin, ObjectDeleteMixin, SaveMixin\n+from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin\n \n __all__ = [\n     \"ProjectRelease\",\n@@ -9,18 +9,21 @@\n ]\n \n \n-class ProjectRelease(RESTObject):\n+class ProjectRelease(SaveMixin, RESTObject):\n     _id_attr = \"tag_name\"\n     _managers = ((\"links\", \"ProjectReleaseLinkManager\"),)\n \n \n-class ProjectReleaseManager(NoUpdateMixin, RESTManager):\n+class ProjectReleaseManager(CRUDMixin, RESTManager):\n     _path = \"/projects/%(project_id)s/releases\"\n     _obj_cls = ProjectRelease\n     _from_parent_attrs = {\"project_id\": \"id\"}\n     _create_attrs = RequiredOptional(\n         required=(\"name\", \"tag_name\", \"description\"), optional=(\"ref\", \"assets\")\n     )\n+    _update_attrs = RequiredOptional(\n+        optional=(\"name\", \"description\", \"milestones\", \"released_at\")\n+    )\n \n \n class ProjectReleaseLink(ObjectDeleteMixin, SaveMixin, RESTObject):\n", "issue": "Deprecate tag.set_release_description and remove it from docs\n## Description of the problem, including code/CLI snippet\r\nIt seems that the code we use to create a release from a tag [here](https://github.com/python-gitlab/python-gitlab/blob/8753add72061ea01c508a42d16a27388b1d92677/gitlab/v4/objects/tags.py#L19) has been deprecated and removed\r\n\r\nWe should update to use the new release API\r\n\r\nI'll try to investigate a little later tonight as it is blocking my team for some automated release tools.\r\n\r\n## Expected Behavior\r\n- set_release_description() create or update a release\r\n\r\n## Actual Behavior\r\n- 404 error\r\n\r\n## Specifications\r\n\r\n  - python-gitlab version: 2.8 (and 2.5)\r\n  - API version you are using (v3/v4): v4\r\n  - Gitlab server version (or gitlab.com): gitlab.com\r\n\n", "before_files": [{"content": "from gitlab.base import RequiredOptional, RESTManager, RESTObject\nfrom gitlab.mixins import CRUDMixin, NoUpdateMixin, ObjectDeleteMixin, SaveMixin\n\n__all__ = [\n    \"ProjectRelease\",\n    \"ProjectReleaseManager\",\n    \"ProjectReleaseLink\",\n    \"ProjectReleaseLinkManager\",\n]\n\n\nclass ProjectRelease(RESTObject):\n    _id_attr = \"tag_name\"\n    _managers = ((\"links\", \"ProjectReleaseLinkManager\"),)\n\n\nclass ProjectReleaseManager(NoUpdateMixin, RESTManager):\n    _path = \"/projects/%(project_id)s/releases\"\n    _obj_cls = ProjectRelease\n    _from_parent_attrs = {\"project_id\": \"id\"}\n    _create_attrs = RequiredOptional(\n        required=(\"name\", \"tag_name\", \"description\"), optional=(\"ref\", \"assets\")\n    )\n\n\nclass ProjectReleaseLink(ObjectDeleteMixin, SaveMixin, RESTObject):\n    pass\n\n\nclass ProjectReleaseLinkManager(CRUDMixin, RESTManager):\n    _path = \"/projects/%(project_id)s/releases/%(tag_name)s/assets/links\"\n    _obj_cls = ProjectReleaseLink\n    _from_parent_attrs = {\"project_id\": \"project_id\", \"tag_name\": \"tag_name\"}\n    _create_attrs = RequiredOptional(\n        required=(\"name\", \"url\"), optional=(\"filepath\", \"link_type\")\n    )\n    _update_attrs = RequiredOptional(optional=(\"name\", \"url\", \"filepath\", \"link_type\"))\n", "path": "gitlab/v4/objects/releases.py"}]}