internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: python-gitlab/python-gitlab

Issue:
Allow runpy invocation of CLI tool (python -m gitlab)
## Description of the problem, including code/CLI snippet

I would like to be able to invoke the CLI without any console_script wrappers by using Python's built-in [runpy module](https://docs.python.org/3/library/runpy.html), i.e.:

```
python -m gitlab --help
```

## Expected Behavior

Invoke the CLI.

## Actual Behavior

Error is emitted:

`No module named gitlab.__main__; 'gitlab' is a package and cannot be directly executed`

## Specifications

  - python-gitlab version: 1.8.0
  - API version you are using (v3/v4): n/a
  - Gitlab server version (or gitlab.com): n/a



Discussion:

Resolving patch:
diff --git a/gitlab/__main__.py b/gitlab/__main__.py
new file mode 100644
--- /dev/null
+++ b/gitlab/__main__.py
@@ -0,0 +1,4 @@
+import gitlab.cli
+
+
+__name__ == '__main__' and gitlab.cli.main()


Test patch:
Repository: python-gitlab/python-gitlab

Issue:
members.all returns dicts instead of REST objects
## Description of the problem, including code/CLI snippet
`project.members.all()` is documented as returning a `RESTObjectList`, but it actually returns a list of `dict`s. Same for groups.

## Expected Behavior
`all()` should return a list of the same type as `list()`.

## Actual Behavior
```
>>> type(gitlab.Gitlab.from_config().projects.list()[0].members.list()[0])
<class 'gitlab.v4.objects.ProjectMember'>
>>> type(gitlab.Gitlab.from_config().projects.list()[0].members.all()[0])
<class 'dict'>
```

## Specifications

  - python-gitlab version: 1.7.0
  - API version you are using (v3/v4): v4
  - Gitlab server version (or gitlab.com): Shouldn't matter.



Discussion:

Resolving patch:
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -740,7 +740,8 @@ def all(self, **kwargs):
         """
 
         path = '%s/all' % self.path
-        return self.gitlab.http_list(path, **kwargs)
+        obj = self.gitlab.http_list(path, **kwargs)
+        return [self._obj_cls(self, item) for item in obj]
 
 
 class GroupMergeRequest(RESTObject):
@@ -1955,7 +1956,8 @@ def all(self, **kwargs):
         """
 
         path = '%s/all' % self.path
-        return self.gitlab.http_list(path, **kwargs)
+        obj = self.gitlab.http_list(path, **kwargs)
+        return [self._obj_cls(self, item) for item in obj]
 
 
 class ProjectNote(RESTObject):


Test patch:
Repository: python-gitlab/python-gitlab

Issue:
Add support for deleting job artifacts
## Description of the problem, including code/CLI snippet
Add support for deleting a job's artifacts, via the `delete-artifacts` API call. 

## Expected Behavior
https://docs.gitlab.com/ee/api/jobs.html#delete-artifacts

## Actual Behavior
Not implemented

## Specifications
https://docs.gitlab.com/ee/api/jobs.html#delete-artifacts



Discussion:

Resolving patch:
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -1584,6 +1584,21 @@ def keep_artifacts(self, **kwargs):
         path = "%s/%s/artifacts/keep" % (self.manager.path, self.get_id())
         self.manager.gitlab.http_post(path)
 
+    @cli.register_custom_action("ProjectJob")
+    @exc.on_http_error(exc.GitlabCreateError)
+    def delete_artifacts(self, **kwargs):
+        """Delete artifacts of a job.
+
+        Args:
+            **kwargs: Extra options to send to the server (e.g. sudo)
+
+        Raises:
+            GitlabAuthenticationError: If authentication is not correct
+            GitlabDeleteError: If the request could not be performed
+        """
+        path = "%s/%s/artifacts" % (self.manager.path, self.get_id())
+        self.manager.gitlab.http_delete(path)
+
     @cli.register_custom_action("ProjectJob")
     @exc.on_http_error(exc.GitlabGetError)
     def artifacts(self, streamed=False, action=None, chunk_size=1024, **kwargs):


Test patch:
diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py
--- a/tools/python_test_v4.py
+++ b/tools/python_test_v4.py
@@ -421,8 +421,9 @@
 
 # commit status
 commit = admin_project.commits.list()[0]
+size = len(commit.statuses.list())
 status = commit.statuses.create({"state": "success", "sha": commit.id})
-assert len(commit.statuses.list()) == 1
+assert len(commit.statuses.list()) == size + 1
 
 assert commit.refs()
 assert commit.merge_requests() is not None
Repository: python-gitlab/python-gitlab

Issue:
Would like to see support for "related_merge_requests"
## Description of the problem, including code/CLI snippet
Gitlab now supports GET /projects/:id/issues/:issue_id/related_merge_requests - If someone can outline the steps needed, I'll be happy to contribute a patch

## Expected Behavior


## Actual Behavior


## Specifications

  - python-gitlab version: 1.8.0
  - API version you are using (v3/v4): v4
  - Gitlab server version (or gitlab.com): 



Discussion:

Resolving patch:
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -2186,6 +2186,24 @@ def move(self, to_project_id, **kwargs):
         server_data = self.manager.gitlab.http_post(path, post_data=data, **kwargs)
         self._update_attrs(server_data)
 
+    @cli.register_custom_action("ProjectIssue")
+    @exc.on_http_error(exc.GitlabGetError)
+    def related_merge_requests(self, **kwargs):
+        """List merge requests related to the issue.
+
+        Args:
+            **kwargs: Extra options to send to the server (e.g. sudo)
+
+        Raises:
+            GitlabAuthenticationError: If authentication is not correct
+            GitlabGetErrot: If the merge requests could not be retrieved
+
+        Returns:
+            list: The list of merge requests.
+        """
+        path = "%s/%s/related_merge_requests" % (self.manager.path, self.get_id())
+        return self.manager.gitlab.http_get(path, **kwargs)
+
     @cli.register_custom_action("ProjectIssue")
     @exc.on_http_error(exc.GitlabGetError)
     def closed_by(self, **kwargs):


Test patch:
diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py
--- a/tools/python_test_v4.py
+++ b/tools/python_test_v4.py
@@ -566,6 +566,8 @@
 
 assert issue1.user_agent_detail()["user_agent"]
 assert issue1.participants()
+assert type(issue1.closed_by()) == list
+assert type(issue1.related_merge_requests()) == list
 
 # issues labels and events
 label2 = admin_project.labels.create({"name": "label2", "color": "#aabbcc"})
Repository: python-gitlab/python-gitlab

Issue:
Rebase an MR
## Description of the problem, including code/CLI snippet
The Gitlab REST API offers a call to attempt to rebase the `source_branch` onto the `target_branch`. This hasn't been implemented in the Python Gitlab client library. I'd like to go ahead and submit an MR for this. However, I was wondering whether there's a reason this hasn't been implemented yet. If there are no objections from your side, I'd be fine creating an MR for this feature.

## Specifications

  - python-gitlab version: 1.8.0
  - API version you are using (v3/v4): v4
  - Gitlab server version (or gitlab.com):



Discussion:
Sure. Please go ahead.

Just make sure to follow our contribution guidelines and use conventional changelog: 
https://github.com/python-gitlab/python-gitlab#contributing

Thank you very much!

> Note: The tests currently still fail in the CI and we're not quite sure why. They work locally just fine
Nice, then I'll get going :)

Resolving patch:
diff --git a/gitlab/exceptions.py b/gitlab/exceptions.py
--- a/gitlab/exceptions.py
+++ b/gitlab/exceptions.py
@@ -173,6 +173,10 @@ class GitlabMRApprovalError(GitlabOperationError):
     pass
 
 
+class GitlabMRRebaseError(GitlabOperationError):
+    pass
+
+
 class GitlabMRClosedError(GitlabOperationError):
     pass
 
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -2712,6 +2712,22 @@ def unapprove(self, **kwargs):
         server_data = self.manager.gitlab.http_post(path, post_data=data, **kwargs)
         self._update_attrs(server_data)
 
+    @cli.register_custom_action("ProjectMergeRequest")
+    @exc.on_http_error(exc.GitlabMRRebaseError)
+    def rebase(self, **kwargs):
+        """Attempt to rebase the source branch onto the target branch
+
+        Args:
+            **kwargs: Extra options to send to the server (e.g. sudo)
+
+        Raises:
+            GitlabAuthenticationError: If authentication is not correct
+            GitlabMRRebaseError: If rebasing failed
+        """
+        path = "%s/%s/rebase" % (self.manager.path, self.get_id())
+        data = {}
+        return self.manager.gitlab.http_put(path, post_data=data, **kwargs)
+
     @cli.register_custom_action(
         "ProjectMergeRequest",
         tuple(),


Test patch:
diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py
--- a/tools/python_test_v4.py
+++ b/tools/python_test_v4.py
@@ -686,6 +686,9 @@
 event = mr.resourcelabelevents.get(events[0].id)
 assert event
 
+# rebasing
+assert mr.rebase()
+
 # basic testing: only make sure that the methods exist
 mr.commits()
 mr.changes()
Repository: python-gitlab/python-gitlab

Issue:
Fix for issue #717
I propose this fix for isuue #717. It fixes `event list`, which didn't worked when invoked from CLI (and probably neither when used from gitlab API).


Discussion:

Resolving patch:
diff --git a/gitlab/cli.py b/gitlab/cli.py
--- a/gitlab/cli.py
+++ b/gitlab/cli.py
@@ -182,7 +182,7 @@ def main():
     if args.fields:
         fields = [x.strip() for x in args.fields.split(",")]
     debug = args.debug
-    action = args.action
+    action = args.whaction
     what = args.what
 
     args = args.__dict__
@@ -193,7 +193,7 @@ def main():
         "verbose",
         "debug",
         "what",
-        "action",
+        "whaction",
         "version",
         "output",
     ):
diff --git a/gitlab/v4/cli.py b/gitlab/v4/cli.py
--- a/gitlab/v4/cli.py
+++ b/gitlab/v4/cli.py
@@ -312,7 +312,7 @@ def extend_parser(parser):
         object_group = subparsers.add_parser(arg_name)
 
         object_subparsers = object_group.add_subparsers(
-            title="action", dest="action", help="Action to execute."
+            title="action", dest="whaction", help="Action to execute."
         )
         _populate_sub_parser_by_class(cls, object_subparsers)
         object_subparsers.required = True
@@ -406,7 +406,7 @@ def display_dict(d, padding):
                 id = getattr(obj, obj._id_attr)
                 print("%s: %s" % (obj._id_attr.replace("_", "-"), id))
             if hasattr(obj, "_short_print_attr"):
-                value = getattr(obj, obj._short_print_attr)
+                value = getattr(obj, obj._short_print_attr) or "None"
                 value = value.replace("\r", "").replace("\n", " ")
                 # If the attribute is a note (ProjectCommitComment) then we do
                 # some modifications to fit everything on one line


Test patch:
diff --git a/gitlab/tests/test_cli.py b/gitlab/tests/test_cli.py
--- a/gitlab/tests/test_cli.py
+++ b/gitlab/tests/test_cli.py
@@ -116,7 +116,7 @@ def test_parse_args(self):
         parser = cli._get_parser(gitlab.v4.cli)
         args = parser.parse_args(["project", "list"])
         self.assertEqual(args.what, "project")
-        self.assertEqual(args.action, "list")
+        self.assertEqual(args.whaction, "list")
 
     def test_parser(self):
         parser = cli._get_parser(gitlab.v4.cli)
Repository: python-gitlab/python-gitlab

Issue:
fix for issue #718
Fix for issue #718.


Discussion:

Resolving patch:
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -3786,7 +3786,7 @@ class Project(SaveMixin, ObjectDeleteMixin, RESTObject):
         ("wikis", "ProjectWikiManager"),
     )
 
-    @cli.register_custom_action("Project", tuple(), ("path", "ref"))
+    @cli.register_custom_action("Project", tuple(), ("path", "ref", "recursive"))
     @exc.on_http_error(exc.GitlabGetError)
     def repository_tree(self, path="", ref="", recursive=False, **kwargs):
         """Return a list of files in the repository.


Test patch:
Repository: python-gitlab/python-gitlab

Issue:
Fix Pickle support: dump() after load() fails
This is a one-liner fix to pickle support: pickle.dump() fails after pickle.load()
```
  File "/home/bourgesl/.local/lib/python3.6/site-packages/gitlab/base.py", line 50, in __getstate__
    module = state.pop("_module")
KeyError: '_module'
```

Reason:
Former self._module call invokes ```set_attr()``` that stores '_module' attribute in ```self.__dict__["_updated_attrs"]["_module"]``` that is not its correct place: ```self.__dict__["_module"]``` as expected by getstate()


Discussion:

Resolving patch:
diff --git a/gitlab/base.py b/gitlab/base.py
--- a/gitlab/base.py
+++ b/gitlab/base.py
@@ -52,7 +52,7 @@ def __getstate__(self):
     def __setstate__(self, state):
         module_name = state.pop("_module_name")
         self.__dict__.update(state)
-        self._module = importlib.import_module(module_name)
+        self.__dict__["_module"] = importlib.import_module(module_name)
 
     def __getattr__(self, name):
         try:


Test patch:
diff --git a/gitlab/tests/test_base.py b/gitlab/tests/test_base.py
--- a/gitlab/tests/test_base.py
+++ b/gitlab/tests/test_base.py
@@ -93,6 +93,7 @@ def test_pickability(self):
         self.assertIsInstance(unpickled, FakeObject)
         self.assertTrue(hasattr(unpickled, "_module"))
         self.assertEqual(unpickled._module, original_obj_module)
+        pickled2 = pickle.dumps(unpickled)
 
     def test_attrs(self):
         obj = FakeObject(self.manager, {"foo": "bar"})
Repository: python-gitlab/python-gitlab

Issue:
Fix constructing Gitlab object without authentication
unauthenticated access is broken since #876 was merged

fixes getting the error `Only one of private_token, oauth_token or job_token should be defined` when using no authentication method at all.


Discussion:
Totally missed that. Thanks for the PR. Would you mind to use the commit conventions? So change to commit message to something like: `fix: allow Gitlab object with auth`

Thank you!
No worries, sometimes it happens that you overlook something. I just noticed the issue today because my chat bot wasn't working anymore :smile: 
Just learned about the commit linter. Good idea to implement that! I hope that it passes now.

Resolving patch:
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -31,7 +31,7 @@
 from gitlab import utils  # noqa
 
 __title__ = "python-gitlab"
-__version__ = "1.12.0"
+__version__ = "1.12.1"
 __author__ = "Gauvain Pocentek"
 __email__ = "gauvainpocentek@gmail.com"
 __license__ = "LGPL3"
@@ -350,13 +350,12 @@ def _construct_url(self, id_, obj, parameters, action=None):
             return url
 
     def _set_auth_info(self):
-        if (
-            sum(
-                bool(arg)
-                for arg in [self.private_token, self.oauth_token, self.job_token]
-            )
-            != 1
-        ):
+        tokens = [
+            token
+            for token in [self.private_token, self.oauth_token, self.job_token]
+            if token
+        ]
+        if len(tokens) > 1:
             raise ValueError(
                 "Only one of private_token, oauth_token or job_token should "
                 "be defined"


Test patch:
Repository: python-gitlab/python-gitlab

Issue:
Add 12.4 deployment API
See:
https://docs.gitlab.com/ce/api/deployments.html#create-a-deployment



Discussion:

Resolving patch:
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -3735,15 +3735,16 @@ def set_approvers(self, approver_ids=None, approver_group_ids=None, **kwargs):
         self.gitlab.http_put(path, post_data=data, **kwargs)
 
 
-class ProjectDeployment(RESTObject):
+class ProjectDeployment(RESTObject, SaveMixin):
     pass
 
 
-class ProjectDeploymentManager(RetrieveMixin, RESTManager):
+class ProjectDeploymentManager(RetrieveMixin, CreateMixin, UpdateMixin, RESTManager):
     _path = "/projects/%(project_id)s/deployments"
     _obj_cls = ProjectDeployment
     _from_parent_attrs = {"project_id": "id"}
     _list_filters = ("order_by", "sort")
+    _create_attrs = (("sha", "ref", "tag", "status", "environment"), tuple())
 
 
 class ProjectProtectedBranch(ObjectDeleteMixin, RESTObject):


Test patch:
diff --git a/gitlab/tests/test_gitlab.py b/gitlab/tests/test_gitlab.py
--- a/gitlab/tests/test_gitlab.py
+++ b/gitlab/tests/test_gitlab.py
@@ -651,6 +651,50 @@ def resp_mark_all_as_done(url, request):
         with HTTMock(resp_mark_all_as_done):
             self.gl.todos.mark_all_as_done()
 
+    def test_deployment(self):
+        content = '{"id": 42, "status": "success", "ref": "master"}'
+        json_content = json.loads(content)
+
+        @urlmatch(
+            scheme="http",
+            netloc="localhost",
+            path="/api/v4/projects/1/deployments",
+            method="post",
+        )
+        def resp_deployment_create(url, request):
+            headers = {"content-type": "application/json"}
+            return response(200, json_content, headers, None, 5, request)
+
+        @urlmatch(
+            scheme="http",
+            netloc="localhost",
+            path="/api/v4/projects/1/deployments/42",
+            method="put",
+        )
+        def resp_deployment_update(url, request):
+            headers = {"content-type": "application/json"}
+            return response(200, json_content, headers, None, 5, request)
+
+        with HTTMock(resp_deployment_create):
+            deployment = self.gl.projects.get(1, lazy=True).deployments.create(
+                {
+                    "environment": "Test",
+                    "sha": "1agf4gs",
+                    "ref": "master",
+                    "tag": False,
+                    "status": "created",
+                }
+            )
+            self.assertEqual(deployment.id, 42)
+            self.assertEqual(deployment.status, "success")
+            self.assertEqual(deployment.ref, "master")
+
+        with HTTMock(resp_deployment_update):
+            json_content["status"] = "failed"
+            deployment.status = "failed"
+            deployment.save()
+            self.assertEqual(deployment.status, "failed")
+
     def test_update_submodule(self):
         @urlmatch(
             scheme="http", netloc="localhost", path="/api/v4/projects/1$", method="get"
Repository: python-gitlab/python-gitlab

Issue:
Add 'include_subgroups' to CLI
## Description of the problem, including code/CLI snippet
Gitlab has recently enriched their APIs, especially with respect to Groups. The GroupProjectManager should be updated with the newly available filters. I'm sure that there are more APIs that have been updated.

https://docs.gitlab.com/ce/api/groups.html#list-a-groups-projects
https://github.com/python-gitlab/python-gitlab/blob/master/gitlab/v4/objects.py#L847

## Expected Behavior
The ability to use the new filters, specifically ``include_subgroups``

## Actual Behavior
CLI errors out stating the parameter is not valid.

## Specifications

  - python-gitlab version: 1.7.0
  - API version you are using (v3/v4): v4
  - Gitlab server version (or gitlab.com): 11.6.5-ee



Discussion:

Resolving patch:
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -1097,6 +1097,7 @@ class GroupProjectManager(ListMixin, RESTManager):
         "owned",
         "starred",
         "with_custom_attributes",
+        "include_subgroups",
     )
 
 


Test patch:
Repository: python-gitlab/python-gitlab

Issue:
Feature idea: autocompletion for CLI mode
## Description of the problem, including code/CLI snippet

Feature/improve suggestion: in many of my cases, I would like to have an autocompletion to have less time to spend at docs and source code to find out all possible combination of commands/object/args.

## Expected Behavior

Would be great to have autocompletion for bash or zsh.

## Actual Behavior

No completion right now.

## Specifications

  - python-gitlab version: 1.6.0
  - API version you are using (v3/v4): 4
  - Gitlab server version (or gitlab.com): gitlab.com



Discussion:
click has completion built in, so the strategy might be "switch from argparse to click".

Resolving patch:
diff --git a/gitlab/cli.py b/gitlab/cli.py
--- a/gitlab/cli.py
+++ b/gitlab/cli.py
@@ -172,6 +172,12 @@ def main():
 
     # Now we build the entire set of subcommands and do the complete parsing
     parser = _get_parser(cli_module)
+    try:
+        import argcomplete
+
+        argcomplete.autocomplete(parser)
+    except Exception:
+        pass
     args = parser.parse_args(sys.argv[1:])
 
     config_files = args.config_file
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -45,4 +45,5 @@ def get_version():
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
     ],
+    extras_require={"autocompletion": ["argcomplete>=1.10.0,<2"]},
 )


Test patch:
Repository: python-gitlab/python-gitlab

Issue:
Automatically retry transient API issues
So I see exceptions like that:

```
DEBUG:urllib3.connectionpool:https://gitlab.com:443 "GET /api/v4/...?...&page=111&per_page=100&... HTTP/1.1" 502 24
Traceback (most recent call last):
  File ".../gitlab/__init__.py", line 832, in next
    item = self._data[self._current]
IndexError: list index out of range

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  ...
  File ".../gitlab/base.py", line 184, in __next__
    return self.next()
  File ".../gitlab/base.py", line 187, in next
    data = self._list.next()
  File ".../gitlab/__init__.py", line 837, in next
    self._query(self._next_url)
  File ".../gitlab/__init__.py", line 766, in _query
    result = self._gl.http_request("get", url, query_data=query_data, **kwargs)
  File ".../gitlab/__init__.py", line 562, in http_request
    response_body=result.content,
gitlab.exceptions.GitlabHttpError: 502: GitLab is not responding
```

Those should just be retried, no?


Discussion:
I don't think so. You need to handle failures yourself. Maybe you want to check the health of your instance with python-gitlab.

```python
try:
    gl.projects.list()
except:
    # do retry
```
But if I in the middle of pagination, then this is something python-gitlab should do? I cannot just resume the generator?
I guess that is true. But then it should be optional maybe. Otherwise we change the behavior of existing scripts. Right?
Sure. A flag like `retry_transient_exceptions=5`. To retry up to 5 times.
I think all 500 errors should be retried, and 429 error.
If we get 429 we already wait until we can request new items again. 

Resolving patch:
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -518,6 +518,8 @@ def http_request(
 
         # obey the rate limit by default
         obey_rate_limit = kwargs.get("obey_rate_limit", True)
+        # do not retry transient errors by default
+        retry_transient_errors = kwargs.get("retry_transient_errors", False)
 
         # set max_retries to 10 by default, disable by setting it to -1
         max_retries = kwargs.get("max_retries", 10)
@@ -531,7 +533,9 @@ def http_request(
             if 200 <= result.status_code < 300:
                 return result
 
-            if 429 == result.status_code and obey_rate_limit:
+            if (429 == result.status_code and obey_rate_limit) or (
+                result.status_code in [500, 502, 503, 504] and retry_transient_errors
+            ):
                 if max_retries == -1 or cur_retries < max_retries:
                     wait_time = 2 ** cur_retries * 0.1
                     if "Retry-After" in result.headers:


Test patch: