Skip to content

feat(api)!: Make RESTObjectList typing generic #3121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 7, 2025

Conversation

igorp-collabora
Copy link
Contributor

@igorp-collabora igorp-collabora commented Feb 6, 2025

BREAKING CHANGE: Type narrowing of list() methods return can become redundant.

Currently the RESTObjectList type hints yielded objects as base RESTObject. However, the ListMixin is now generic and will return the RESTObject subclass based on the RESTManager typing.

Using typing.Generic it is possible to make RESTObjectList type hint a specific subclass of the RESTObject.

Iterating over list() call the ListMixin will now yield the same object class because both list and RESTObjectList will have the same type hinted subclass.

Closes #2062

@igorp-collabora
Copy link
Contributor Author

I made this simple python file to check type hints:

import typing
from gitlab.v4.objects import MergeRequestManager


def test_list(mang: MergeRequestManager) -> None:
    for m in mang.list():
        typing.reveal_type(m)

When run on main branch the revealed type will be:

typing_rest_list.py:7: note: Revealed type is "gitlab.base.RESTObject"

Using this branch the revealed type will be:

typing_rest_list.py:7: note: Revealed type is "gitlab.v4.objects.merge_requests.MergeRequest"

I believe this is because both base.RESTObjectList[base.TObjCls] | list[base.TObjCls] will yield TObjCls when iterated on. Not sure how much more value the overloads will bring but they can raise a deprecation warning when the get_all is not used.

Copy link

codecov bot commented Feb 6, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.28%. Comparing base (9040dbe) to head (d290a21).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3121   +/-   ##
=======================================
  Coverage   97.28%   97.28%           
=======================================
  Files          97       97           
  Lines        5975     5976    +1     
=======================================
+ Hits         5813     5814    +1     
  Misses        162      162           
Flag Coverage Δ
api_func_v4 83.41% <95.23%> (-0.07%) ⬇️
cli_func_v4 84.50% <95.23%> (+<0.01%) ⬆️
unit 90.07% <95.23%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
gitlab/base.py 100.00% <100.00%> (ø)
gitlab/mixins.py 91.34% <100.00%> (ø)
gitlab/v4/cli.py 91.85% <100.00%> (ø)
gitlab/v4/objects/ldap.py 78.26% <100.00%> (ø)
gitlab/v4/objects/merge_requests.py 90.25% <100.00%> (ø)
gitlab/v4/objects/milestones.py 100.00% <100.00%> (ø)
gitlab/v4/objects/snippets.py 100.00% <100.00%> (ø)
gitlab/v4/objects/users.py 99.15% <100.00%> (ø)

Copy link
Member

@nejch nejch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @igorp-collabora again! This LGTM.

Could you maybe add a breaking change footer as outlined in https://www.conventionalcommits.org/en/v1.0.0/, with a short sentence outlying the return types for list endpoints will now be the real object rather than RESTObject?

This way it should be easier for downstream users to migrate to our new major bump (I'll look at other deprecations in our code and maybe add more breaking changes as well this month).

@igorp-collabora igorp-collabora force-pushed the rest-object-list-generic branch from 77cb2e9 to a24c2cf Compare February 7, 2025 12:55
@igorp-collabora igorp-collabora changed the title feat(api): Make RESTObjectList typing generic feat(api)!: Make RESTObjectList typing generic Feb 7, 2025
BREAKING CHANGE: Type narrowing of `list()` methods return objects
from RESTObject to a concrete subclass (for example `MergeRequest`)
can become redundant.

Currently the RESTObjectList type hints yielded objects
as base RESTObject. However, the ListMixin is now generic
and will return the RESTObject subclass based on the RESTManager
typing.

Using `typing.Generic` it is possible to make RESTObjectList
type hint a specific subclass of the RESTObject.

Iterating over `list()` call the ListMixin will now yield
the same object class because both `list` and `RESTObjectList`
will have the same type hinted subclass.

Signed-off-by: Igor Ponomarev <[email protected]>
@igorp-collabora igorp-collabora force-pushed the rest-object-list-generic branch from a24c2cf to d290a21 Compare February 7, 2025 12:58
@igorp-collabora
Copy link
Contributor Author

I added the breaking changes footer to the commit message and an exclamation mark to the commit summary.

@nejch nejch enabled auto-merge (rebase) February 7, 2025 13:02
@nejch nejch merged commit befba35 into python-gitlab:main Feb 7, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Type hint on ListMixin.list is too strict
2 participants