You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ProjectMember.save() does not work because 'ProjectMemberAllManager' object has no attribute 'update' #1825
Description of the problem, including code/CLI snippet
ProjectMember.save() does not work because 'ProjectMemberAllManager' object has no attribute 'update'.
project = GitlabClient().projects.get('my_proj_name')
member = project.members.list()[0]
member.access_level = 30
member.save()
Expected Behavior
Member saves with new properties.
Actual Behavior
Traceback (most recent call last):
File "gitlab_client.py", line 85, in update_project_permissions
member.save()
File "/Users/theoturner/Library/Python/3.8/lib/python/site-packages/gitlab/mixins.py", line 551, in save
server_data = self.manager.update(obj_id, updated_data, **kwargs)
AttributeError: 'ProjectMemberAllManager' object has no attribute 'update'
N.B. type(member) is <class 'gitlab.v4.objects.members.ProjectMember'> so I haven't accidentally got a ProjectMemberAllManager.
Specifications
python-gitlab version: 3.0.0, can be replicated in 2.8 and above
API version you are using (v3/v4): v4
Note: John Villalovos accidentally edited this and now attempting to return to original state...
This is a bit of a conceptional issue. Basically python-gitlab tries to be a small as possible layer on top of the GitLab API as possible. So there is less automatic logic that you might expect, as this reduces complexity of the library a lot
To update a member, you would need to get the exact member and update this object. You cannot update a list, as python-gitlab in it's principle cannot know what you're trying to update.
Basically you need to do:
project=GitlabClient().projects.get('my_proj_name')
member=project.members.list()[0]
member=project.members.get(member.id) # add this linemember.access_level=30member.save()
And after saying all that. That is why it has a RetrieveMixin.
So my theory is that the code should be:
project = GitlabClient().projects.get('my_proj_name')
member = project.members_all.list()[0]
member = project.members_all.get(member.id) # add this line
member.access_level = 30
member.save()
Notice everything is members_all
But not sure that will work. Because still ProjectMemberAllManager 😟
Really should make sure to use project.members.list() for best results.
project = GitlabClient().projects.get('my_proj_name')
member = project.members.list()[0]
member.access_level = 30
member.save()
@theoturner I'm assuming that the actual call was member = project.members_all.list() as otherwise I'm not sure how would get a ProjectMemberAllManager
Activity
max-wittig commentedon Jan 11, 2022
This is a bit of a conceptional issue. Basically
python-gitlabtries to be a small as possible layer on top of the GitLab API as possible. So there is less automatic logic that you might expect, as this reduces complexity of the library a lotTo update a member, you would need to get the exact member and update this object. You cannot update a list, as python-gitlab in it's principle cannot know what you're trying to update.
Basically you need to do:
Does that clarify the usage?
JohnVillalovos commentedon Jan 11, 2022
@max-wittig @nejch
This does make me wonder, why can'tProjectMemberAllManager' use aCRUDMixin`?Figured it out. Because the
pathis.../members/all/JohnVillalovos commentedon Jan 11, 2022
Well we should have agetmethod based on:https://docs.gitlab.com/ee/api/members.html#get-a-member-of-a-group-or-project-including-inherited-and-invited-membersNever mind it does.As I note if do just a
project.members.get(ID)it won't work if theIDis not a direct member of the group.In trying as a
CRUDMixinsave()and others won't work due to the path having/members/all/JohnVillalovos commentedon Jan 11, 2022
And after saying all that. That is why it has a
RetrieveMixin.So my theory is that the code should be:
Notice everything is
members_allBut not sure that will work. Because still
ProjectMemberAllManager😟Really should make sure to use
project.members.list()for best results.JohnVillalovos commentedon Jan 11, 2022
@theoturner I'm assuming that the actual call was
member = project.members_all.list()as otherwise I'm not sure how would get aProjectMemberAllManagerfix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix: members: use new *All objects for *AllManager managers
fix(members): use new *All objects for *AllManager managers