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

Issue:
Add 'note_events' or 'comments' to ProjectHook
Would it be possible to add attributes for note_events (aka comments) and also Wiki Page events in webhooks?

Scanning through the code I think it should be added here: https://github.com/gpocentek/python-gitlab/blob/master/gitlab/objects.py#L1025

I would like to know whether that's all or if there's more to it. I would gladly try the MR myself in a couple of days.



Discussion:
Hey,

Yes you can simply add `note_events` to the attributes list, it should be enough.

I'm not sure about wiki events though, is it supported by the API?

I don't think wiki events are supported by the API, as [the docs](http://docs.gitlab.com/ce/api/projects.html#add-project-hook) don't state anything about it. But honestly, I'm just interested in note_events, I just mentioned wiki events for completeness sake.

Nice then, I will submit the PR. My first ever contribution in Python, I believe.


Resolving patch:
diff --git a/gitlab/objects.py b/gitlab/objects.py
--- a/gitlab/objects.py
+++ b/gitlab/objects.py
@@ -1021,7 +1021,7 @@ class ProjectHook(GitlabObject):
     _url = '/projects/%(project_id)s/hooks'
     requiredUrlAttrs = ['project_id']
     requiredCreateAttrs = ['url']
-    optionalCreateAttrs = ['push_events', 'issues_events',
+    optionalCreateAttrs = ['push_events', 'issues_events', 'note_events',
                            'merge_requests_events', 'tag_push_events',
                            'build_events', 'enable_ssl_verification']
     shortPrintAttr = 'url'


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

Issue:
Erasing builds is not supported
The [documentation](https://python-gitlab.readthedocs.io/en/stable/gl_objects/builds.html#id3) indicates that you can erase a build:

``` python
build.delete()
```

But when I try to do this, I get a `NotImplementedError`:

```
  File "/usr/lib/python2.7/site-packages/gitlab/objects.py", line 326, in delete
    raise NotImplementedError
NotImplementedError
```

This happens because [`canDelete = False`](https://github.com/gpocentek/python-gitlab/blob/90ad2dec7a0b158b2e77ae0cb403b01f2e1498d4/gitlab/objects.py#L942-L948) in the `ProjectBuild` class.

For whatever reason, the GitLab team decided to make erasing a build a  [`POST /projects/:id/builds/:build_id/erase`](https://docs.gitlab.com/ce/api/builds.html#erase-a-build), instead of a `DELETE`, like many of their other APIs.

Regardless, it looks like we will need to special-case this operation to POST.  Which option would you prefer?
1. Override the `delete` method of `ProjectBuild`
2. Add an `erase` method to `ProjectBuild`

Seeing as GitLab might make the deletion more fine-grained in the future (e.g. I hope they eventually allow erasing only artifacts, keeping the trace), I would prefer option 2.

---

GitLab version:  8.12.3
python-gitlab version: 0.15.1



Discussion:

Resolving patch:
diff --git a/docs/gl_objects/builds.py b/docs/gl_objects/builds.py
--- a/docs/gl_objects/builds.py
+++ b/docs/gl_objects/builds.py
@@ -103,10 +103,6 @@ def __call__(self, chunk):
 build.retry()
 # end retry
 
-# delete
-gl.project_builds.delete(build_id, project_id=1)
-# or
-project.builds.delete(build_id)
-# or
-build.delete()
-# end delete
+# erase
+build.erase()
+# end erase
diff --git a/gitlab/exceptions.py b/gitlab/exceptions.py
--- a/gitlab/exceptions.py
+++ b/gitlab/exceptions.py
@@ -95,6 +95,10 @@ class GitlabBuildRetryError(GitlabRetryError):
     pass
 
 
+class GitlabBuildEraseError(GitlabRetryError):
+    pass
+
+
 class GitlabPipelineRetryError(GitlabRetryError):
     pass
 
diff --git a/gitlab/objects.py b/gitlab/objects.py
--- a/gitlab/objects.py
+++ b/gitlab/objects.py
@@ -961,6 +961,12 @@ def retry(self, **kwargs):
         r = self.gitlab._raw_post(url)
         raise_error_from_response(r, GitlabBuildRetryError, 201)
 
+    def erase(self, **kwargs):
+        """Erase the build (remove build artifacts and trace)."""
+        url = '/projects/%s/builds/%s/erase' % (self.project_id, self.id)
+        r = self.gitlab._raw_post(url)
+        raise_error_from_response(r, GitlabBuildEraseError, 201)
+
     def keep_artifacts(self, **kwargs):
         """Prevent artifacts from being delete when expiration is set.
 


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

Issue:
ProjectMergeRequest.changes() returns commit instead of changes
Hi,

I think there is a typo in this line which leads to a bug:

https://github.com/gpocentek/python-gitlab/blob/master/gitlab/objects.py#L1608

When querying a merge request for the changes, it returns the associated commits.

Cheers



Discussion:

Resolving patch:
diff --git a/gitlab/objects.py b/gitlab/objects.py
--- a/gitlab/objects.py
+++ b/gitlab/objects.py
@@ -1605,7 +1605,7 @@ def changes(self, **kwargs):
             GitlabConnectionError: If the server cannot be reached.
             GitlabListError: If the server fails to perform the request.
         """
-        url = ('/projects/%s/merge_requests/%s/commits' %
+        url = ('/projects/%s/merge_requests/%s/changes' %
                (self.project_id, self.id))
         r = self.gitlab._raw_get(url, **kwargs)
         raise_error_from_response(r, GitlabListError)


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

Issue:
Missing pipeline_events in hooks
https://github.com/gpocentek/python-gitlab/blob/master/gitlab/objects.py#L1418

pipeline_events should be in here, and it's missing. 

This results in creating a hook with no pipeline_events, but all the other events.

If you update a hook, it will update everything except for this. 

It just uses the default value of False.





Discussion:

Resolving patch:
diff --git a/gitlab/objects.py b/gitlab/objects.py
--- a/gitlab/objects.py
+++ b/gitlab/objects.py
@@ -1417,7 +1417,8 @@ class ProjectHook(GitlabObject):
     requiredCreateAttrs = ['url']
     optionalCreateAttrs = ['push_events', 'issues_events', 'note_events',
                            'merge_requests_events', 'tag_push_events',
-                           'build_events', 'enable_ssl_verification', 'token']
+                           'build_events', 'enable_ssl_verification', 'token',
+                           'pipeline_events']
     shortPrintAttr = 'url'
 
 


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

Issue:
Trigger variables ignored with v4 API
Since I switched to v4 API, the variables I pass to triggers are ignored. Here is a sample of code:

```
from httplib import HTTPConnection
HTTPConnection.debuglevel = 2
my_project.trigger_pipeline('gitlabci', 'XXXXX', {'variables[GITLAB_TEST]': 'ThisIsATest'})
```

From `httplib` debug output it's equivalent to:

```
curl --request POST https://gitlab.com/api/v4/projects/XXXX/trigger/pipeline -H "Content-Type: application/json" -d '{"token": "XXXXX", "ref": "gitlabci", "variables[GITLAB_TEST]": "ThisIsATest"}'
```

which also ignore variables. Doing the same without JSON does work:

```
curl --request POST https://gitlab.com/api/v4/projects/XXXX/trigger/pipeline  --form token=XXXXX --form ref=gitlabci --form "variables[GITLAB_TEST]=ThisIsATest"
```

Would it be possible that Gitlab expect the JSON payload to have an other structure ?


Discussion:
After some trial I found the valid JSON structure:
```json
{
 "token": "XXXXX",
 "ref": "gitlabci",
 "variables": {"GITLAB_TEST": "ThisIsATest"}
}
```

Resolving patch:
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -19,8 +19,6 @@
 from __future__ import absolute_import
 import base64
 
-import six
-
 from gitlab.base import *  # noqa
 from gitlab import cli
 from gitlab.exceptions import *  # noqa
@@ -2080,9 +2078,7 @@ def trigger_pipeline(self, ref, token, variables={}, **kwargs):
             GitlabCreateError: If the server failed to perform the request
         """
         path = '/projects/%s/trigger/pipeline' % self.get_id()
-        form = {r'variables[%s]' % k: v for k, v in six.iteritems(variables)}
-        post_data = {'ref': ref, 'token': token}
-        post_data.update(form)
+        post_data = {'ref': ref, 'token': token, 'variables': variables}
         self.manager.gitlab.http_post(path, post_data=post_data, **kwargs)
 
     # see #56 - add file attachment features


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

Issue:
Pagination generator with non-default per_page
Currently if you request `xxx.list(as_list=False, per_page=100) you end up getting a list instead of the generator.

I think the logic in in [http_list](https://github.com/python-gitlab/python-gitlab/blob/7efbc30b9d8cf8ea856b68ab85b9cd2340121358/gitlab/__init__.py#L715) needs some rework.
Perhaps just removing the `'per_page' in kwargs` condition [from here](https://github.com/python-gitlab/python-gitlab/blob/7efbc30b9d8cf8ea856b68ab85b9cd2340121358/gitlab/__init__.py#L746)

I should be able to specify something like...

```python
my_generator = gl.projects.list(per_page=100, as_list=False)
```

... and still get a generator.  Then I can hook it up to a progress bar like:

```python
my_generator = gl.projects.list(per_page=100, as_list=False, membership=True)
with click.progressbar(my_generator, length=my_generator.total, label='Projects') as bar:
    for project in bar:
        pass
```

The above code generates the following error:

```
AttributeError: 'list' object has no attribute 'total'
```

Today if I want to use the generator function I have to leave the `per_page` off and get them only 20 at a time; this makes it much slower.


Discussion:

Resolving patch:
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -743,7 +743,7 @@ def http_list(self, path, query_data={}, as_list=None, **kwargs):
         if get_all is True:
             return list(GitlabList(self, url, query_data, **kwargs))
 
-        if 'page' in kwargs or 'per_page' in kwargs or as_list is True:
+        if 'page' in kwargs or as_list is True:
             # pagination requested, we return a list
             return list(GitlabList(self, url, query_data, get_next=False,
                                    **kwargs))


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

Issue:
group.members.get only working if result is within first 20
## Description of the problem, including code/CLI snippet

`group.members.get(userid)` only seems to be working if that userid is within first 20 hits.
Run this on any group with more than 20 members:

```python
group = gl.groups.get('some-group')
# iterate over the exhaustive list of members as a generator
for member in group.members.list(as_list=False):
    # so this call should never fail; but it does
    group.members.get(member.id)
```

## Expected Behavior

Ultimately it should call `https://docs.gitlab.com/ce/api/members.html#get-a-member-of-a-group-or-project` with the exact group id and user id.  This would be most efficient.

Alternatively it could call `.list()` in such a way that it is able to iterate over all results. For example `.list(as_list=False)` to force a generator to be returned or `.list(all=True)` to force the exhaustive list to be returned.  But again, this is bad if there is a more efficient API to call as linked to above.

## Actual Behavior

It ends up calling `GetFromListMixin` which ends up calling `http_list` with no arguments which just returns 20 items.  It then compares those id's to the requested one.

## Specifications

  - python-gitlab version: 1.3.0
  - API version you are using (v3/v4): 4




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
@@ -547,7 +547,7 @@ class GroupMember(SaveMixin, ObjectDeleteMixin, RESTObject):
     _short_print_attr = 'username'
 
 
-class GroupMemberManager(GetFromListMixin, CreateMixin, UpdateMixin,
+class GroupMemberManager(ListMixin, GetMixin, CreateMixin, UpdateMixin,
                          DeleteMixin, RESTManager):
     _path = '/groups/%(group_id)s/members'
     _obj_cls = GroupMember


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

Issue:
http_request method of Gitlab class should accept None as the default value for param post_data
http_request method of Gitlab class (in the file \_\_init__.py) should accept None as the default value for param post_data.

For some caching servers, they reject HTTP GET request with body. If post_data's default value is {}, the request body of a GET request will get content b'{}' with Content-length header, which some caching server will just respond with an error. To maximize the support, I feel it suitable to change post_data's default value to None. Also it is not best practice in Python to use a mutable default value as an argument. 

I didn't have time to read all the code. So let me know if this change is appropriate. 





Discussion:

Resolving patch:
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -362,7 +362,7 @@ def _build_url(self, path):
         else:
             return '%s%s' % (self._url, path)
 
-    def http_request(self, verb, path, query_data={}, post_data={},
+    def http_request(self, verb, path, query_data={}, post_data=None,
                      streamed=False, files=None, **kwargs):
         """Make an HTTP request to the Gitlab server.
 


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

Issue:
gitlab --help requires a config file
## Description of the problem, including code/CLI snippet

`gitlab --help` reads its config file even when displaying help

## Expected Behavior

Print out the help text.

## Actual Behavior

Exits with error if no configuration file is found.

## Specifications

  - python-gitlab version: 1.5.0



Discussion:

Resolving patch:
diff --git a/gitlab/cli.py b/gitlab/cli.py
--- a/gitlab/cli.py
+++ b/gitlab/cli.py
@@ -98,7 +98,7 @@ def _get_base_parser(add_help=True):
                               "will be used."),
                         required=False)
     parser.add_argument("-o", "--output",
-                        help=("Output format (v4 only): json|legacy|yaml"),
+                        help="Output format (v4 only): json|legacy|yaml",
                         required=False,
                         choices=['json', 'legacy', 'yaml'],
                         default="legacy")
@@ -135,6 +135,10 @@ def main():
         exit(0)
 
     parser = _get_base_parser(add_help=False)
+    if "--help" in sys.argv or "-h" in sys.argv:
+        parser.print_help()
+        exit(0)
+
     # This first parsing step is used to find the gitlab config to use, and
     # load the propermodule (v3 or v4) accordingly. At that point we don't have
     # any subparser setup


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

Issue:
yaml package is not listed as requirement
Using the CLI with yaml output option doesn't work if the `PyYaml` package is not installed.
Maybe it should be listed in the requirements.txt and setup.py

At least it should be noted in the documentation


Discussion:
Hi @max-wittig 

At the time I didn't want to add an extra dependency for people not using the yaml output, or not using the CLI at all. I'm not sure that it's the best idea.
Then I will add it to the docs, that PyYaml is required for this feature to work. 

Resolving patch:
diff --git a/gitlab/v4/cli.py b/gitlab/v4/cli.py
--- a/gitlab/v4/cli.py
+++ b/gitlab/v4/cli.py
@@ -302,14 +302,24 @@ def display_list(self, data, fields, **kwargs):
 
 class YAMLPrinter(object):
     def display(self, d, **kwargs):
-        import yaml  # noqa
-        print(yaml.safe_dump(d, default_flow_style=False))
+        try:
+            import yaml  # noqa
+            print(yaml.safe_dump(d, default_flow_style=False))
+        except ImportError:
+            exit("PyYaml is not installed.\n"
+                 "Install it with `pip install PyYaml` "
+                 "to use the yaml output feature")
 
     def display_list(self, data, fields, **kwargs):
-        import yaml  # noqa
-        print(yaml.safe_dump(
-            [get_dict(obj, fields) for obj in data],
-            default_flow_style=False))
+        try:
+            import yaml  # noqa
+            print(yaml.safe_dump(
+                [get_dict(obj, fields) for obj in data],
+                default_flow_style=False))
+        except ImportError:
+            exit("PyYaml is not installed.\n"
+                 "Install it with `pip install PyYaml` "
+                 "to use the yaml output feature")
 
 
 class LegacyPrinter(object):


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

Issue:
Error messages are not converted from bytes to str in Python 3
## Description of the problem, including code/CLI snippet

When trying to create webhooks on a repository with invalid URLs (like 127.x.x.x), GitLab returns HTTP 422 with a JSON body : `{"error":"Invalid url given"}`. Under Python 3, the GitlabCreateError does not convert from bytes to str :

``` python
from gitlab import Gitlab
from gitlab.exceptions import GitlabCreateError

gl = Gitlab('https://gitlab.com', oauth_token="<TOKEN>")
project = gl.projects.get('<PROJECT>')

try:
    project.webhooks.create({'url': 'http://127.0.0.1/'})
except GitlabCreateError as e:
    print(str(e))
```

## Expected Behavior

Under both Python 2 and 3, the above snippet should print

```
422: {"error": "Invalid url given"}
```

## Actual Behavior

Under Python 2, it works as expected. Under Python 3 only, this prints

```
422: b'{"error": "Invalid url given"}'
```

## Specifications

  - python-gitlab version: 1.5.1
  - API version you are using (v3/v4): v4
  - Gitlab server version (or gitlab.com): GitLab.com (11.4.0-rc7-ee)



Discussion:

Resolving patch:
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -490,10 +490,14 @@ def http_request(self, verb, path, query_data={}, post_data=None,
                 time.sleep(wait_time)
                 continue
 
+            error_message = result.content
             try:
-                error_message = result.json()['message']
+                error_json = result.json()
+                for k in ('message', 'error'):
+                    if k in error_json:
+                        error_message = error_json[k]
             except (KeyError, ValueError, TypeError):
-                error_message = result.content
+                pass
 
             if result.status_code == 401:
                 raise GitlabAuthenticationError(
diff --git a/gitlab/exceptions.py b/gitlab/exceptions.py
--- a/gitlab/exceptions.py
+++ b/gitlab/exceptions.py
@@ -28,7 +28,12 @@ def __init__(self, error_message="", response_code=None,
         # Full http response
         self.response_body = response_body
         # Parsed error message from gitlab
-        self.error_message = error_message
+        try:
+            # if we receive str/bytes we try to convert to unicode/str to have
+            # consistent message types (see #616)
+            self.error_message = error_message.decode()
+        except Exception:
+            self.error_message = error_message
 
     def __str__(self):
         if self.response_code is not None:


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

Issue:
Allow users to be added to merge/push rules of protected branches
## Description of the problem, including code/CLI snippet

The `project.protectedbranches.create()` method currently does not allow me to configure specific users push and merge rules. Is that hard to add?

[GitLab API docs](https://docs.gitlab.com/ee/api/protected_branches.html#example-with-user--group-level-access) show how to add a user to a protected branch.

## Expected Behavior

Able to set users to be able to merge/push to the protected branch.

## Actual Behavior

No option 

## Specifications

  - python-gitlab version: 1.6.0
  - API version you are using (v3/v4): v4
  - Gitlab server version (or gitlab.com): 11.2



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
@@ -3117,7 +3117,10 @@ class ProjectProtectedBranchManager(NoUpdateMixin, RESTManager):
     _path = '/projects/%(project_id)s/protected_branches'
     _obj_cls = ProjectProtectedBranch
     _from_parent_attrs = {'project_id': 'id'}
-    _create_attrs = (('name', ), ('push_access_level', 'merge_access_level'))
+    _create_attrs = (('name', ),
+                     ('push_access_level', 'merge_access_level',
+                      'unprotect_access_level', 'allowed_to_push',
+                      'allowed_to_merge', 'allowed_to_unprotect'))
 
 
 class ProjectRunner(ObjectDeleteMixin, RESTObject):


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

Issue:
Python gitlab "reset_time_estimate" crashes with HTTP error 404
Just a typo here:

https://github.com/python-gitlab/python-gitlab/blob/85ac10200805de480a076760368336c8135e5acf/gitlab/mixins.py#L535

Fixed by:
`path = '%s/%s/reset_time_estimate' % (self.manager.path, self.get_id())`

Can we do this without pull request?

Thanks for these decent python-gitlab bindings!


Discussion:

Resolving patch:
diff --git a/gitlab/mixins.py b/gitlab/mixins.py
--- a/gitlab/mixins.py
+++ b/gitlab/mixins.py
@@ -532,7 +532,7 @@ def reset_time_estimate(self, **kwargs):
             GitlabAuthenticationError: If authentication is not correct
             GitlabTimeTrackingError: If the time tracking update cannot be done
         """
-        path = '%s/%s/rest_time_estimate' % (self.manager.path, self.get_id())
+        path = '%s/%s/reset_time_estimate' % (self.manager.path, self.get_id())
         return self.manager.gitlab.http_post(path, **kwargs)
 
     @cli.register_custom_action(('ProjectIssue', 'ProjectMergeRequest'),


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

Issue:
user_activities.list() : "from" parameter ?
## Description of the problem, including code/CLI snippet

how did you implement the "from" parameter in the function : 

`activities = gl.user_activities.list(all=True, as_list=False,  from='2018-01-01')`

found in the API : https://docs.gitlab.com/ce/api/users.html#get-user-activities-admin-only

thank you

  - python-gitlab version: 1.5.1
  - API version you are using (v3/v4): v4
  - Gitlab server version (or gitlab.com): 11.4.4



Discussion:
@jmbeuken 

Well it is not possible to use `from` for now as it obviously conflicts with the python keyword. We'll need to implement a workaround for this.

Thanks for raising the issue!

Resolving patch:
diff --git a/gitlab/__init__.py b/gitlab/__init__.py
--- a/gitlab/__init__.py
+++ b/gitlab/__init__.py
@@ -445,7 +445,20 @@ def http_request(self, verb, path, query_data={}, post_data=None,
 
         params = {}
         utils.copy_dict(params, query_data)
-        utils.copy_dict(params, kwargs)
+
+        # Deal with kwargs: by default a user uses kwargs to send data to the
+        # gitlab server, but this generates problems (python keyword conflicts
+        # and python-gitlab/gitlab conflicts).
+        # So we provide a `query_parameters` key: if it's there we use its dict
+        # value as arguments for the gitlab server, and ignore the other
+        # arguments, except pagination ones (per_page and page)
+        if 'query_parameters' in kwargs:
+            utils.copy_dict(params, kwargs['query_parameters'])
+            for arg in ('per_page', 'page'):
+                if arg in kwargs:
+                    params[arg] = kwargs[arg]
+        else:
+            utils.copy_dict(params, kwargs)
 
         opts = self._get_session_opts(content_type='application/json')
 


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
@@ -773,7 +773,7 @@
 assert(len(snippets) == 0)
 
 # user activities
-gl.user_activities.list()
+gl.user_activities.list(query_parameters={'from': '2019-01-01'})
 
 # events
 gl.events.list()