Repository: python-gitlab/python-gitlab

Issue:
CLI: gitlab user-project list doesn't work
## Description of the problem, including code/CLI snippet

`gitlab user-project list --user-id  42` fails.

A similar issue has previously been reported in  #881 .

## Expected Behavior

List of projects owned by the current user are shown.

## Actual Behavior

`Impossible to list objects ('user_id')`  is printed.

## Specifications

  - python-gitlab version: 3.14.0
  - API version you are using (v3/v4): v4
  - Gitlab server version (or gitlab.com): GitLab Community Edition [15.11.0](https://gitlab.com/gitlab-org/gitlab-foss/-/tags/v15.11.0)

## Notes

So I solved my particular problem by hard-coding my user-id in gitlab/v4/objects/user.py l. 641 (in the UserProjectManager list method). Obviously not a general solution, but maybe it helps to track down the error or someone else who comes across this. :)

Furthermore, what I really don't understand is why no KeyError is raised when the format string is processed.


Discussion:
Looks like a regression from https://github.com/python-gitlab/python-gitlab/commit/ac1c619cae6481833f5df91862624bf0380fef67, as we started deleting kwargs for other reasons, so by the time we're doing `do_list()` in the CLI the `user_id` is already gone.
It's interesting that there's no issue with API, only with CLI.

Below code 
```
user = gl.users.get(3)
print(user.projects.list())
```
gets and prints the project list without any issue.
@w7089 it's mostly because of how the CLI constructs the methods called. Some arguments get passed around in `run()` and get cleaned up erroneously in this case because we use a custom method that expects the arguments used a little differently from our normal mixins.
@nejch I believe the fix is as simple as adding `self.mgr._from_parent_attrs = self.parent_args` [here](https://github.com/python-gitlab/python-gitlab/blob/86eba06736b7610d8c4e77cd96ae6071c40067d5/gitlab/v4/cli.py#L48). I tried locally and the issue got resolved. 

If it's acceptable, i'll open a PR after testing of other managers. 

I may be wrong as well and miss something as it's my first ever PR here. 
> If it's acceptable, i'll open a PR after testing of other managers.

Please feel free to open a PR if you think you have a valid fix. Thanks.
I think the main reason for this is because of `UserProjectManager` and the fact that the `path` has to be regenerated.

https://github.com/python-gitlab/python-gitlab/blob/86eba06736b7610d8c4e77cd96ae6071c40067d5/gitlab/v4/objects/users.py#L575-L641

So maybe the idea of setting the parent attributes is correct but I'm not sure.

Resolving patch:
diff --git a/gitlab/v4/cli.py b/gitlab/v4/cli.py
--- a/gitlab/v4/cli.py
+++ b/gitlab/v4/cli.py
@@ -46,7 +46,7 @@ def __init__(
 
         self.mgr_cls._path = self.mgr_cls._path.format(**self.parent_args)
         self.mgr = self.mgr_cls(gl)
-
+        self.mgr._from_parent_attrs = self.parent_args
         if self.mgr_cls._types:
             for attr_name, type_cls in self.mgr_cls._types.items():
                 if attr_name in self.args.keys():
diff --git a/gitlab/v4/objects/users.py b/gitlab/v4/objects/users.py
--- a/gitlab/v4/objects/users.py
+++ b/gitlab/v4/objects/users.py
@@ -666,7 +666,7 @@ def list(self, **kwargs: Any) -> Union[RESTObjectList, List[RESTObject]]:
         if self._parent:
             path = f"/users/{self._parent.id}/projects"
         else:
-            path = f"/users/{kwargs['user_id']}/projects"
+            path = f"/users/{self._from_parent_attrs['user_id']}/projects"
         return ListMixin.list(self, path=path, **kwargs)
 
 


Test patch:
diff --git a/tests/functional/cli/test_cli_users.py b/tests/functional/cli/test_cli_users.py
--- a/tests/functional/cli/test_cli_users.py
+++ b/tests/functional/cli/test_cli_users.py
@@ -12,3 +12,10 @@ def test_create_user_impersonation_token_with_scopes(gitlab_cli, user):
     ret = gitlab_cli(cmd)
 
     assert ret.success
+
+
+def test_list_user_projects(gitlab_cli, user):
+    cmd = ["user-project", "list", "--user-id", user.id]
+    ret = gitlab_cli(cmd)
+
+    assert ret.success