Skip to content

Commit e6582a3

Browse files
authored
Merge pull request #1694 from python-gitlab/jlvillal/const_explicit
refactor: explicitly import gitlab.const values into top-level namespace
2 parents 09a973e + b3b0b5f commit e6582a3

File tree

14 files changed

+140
-73
lines changed

14 files changed

+140
-73
lines changed

docs/gl_objects/access_requests.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ Users can request access to groups and projects.
77
When access is granted the user should be given a numerical access level. The
88
following constants are provided to represent the access levels:
99

10-
* ``gitlab.GUEST_ACCESS``: ``10``
11-
* ``gitlab.REPORTER_ACCESS``: ``20``
12-
* ``gitlab.DEVELOPER_ACCESS``: ``30``
13-
* ``gitlab.MAINTAINER_ACCESS``: ``40``
14-
* ``gitlab.OWNER_ACCESS``: ``50``
10+
* ``gitlab.const.GUEST_ACCESS``: ``10``
11+
* ``gitlab.const.REPORTER_ACCESS``: ``20``
12+
* ``gitlab.const.DEVELOPER_ACCESS``: ``30``
13+
* ``gitlab.const.MAINTAINER_ACCESS``: ``40``
14+
* ``gitlab.const.OWNER_ACCESS``: ``50``
1515

1616
References
1717
----------
@@ -43,7 +43,7 @@ Create an access request::
4343
Approve an access request::
4444

4545
ar.approve() # defaults to DEVELOPER level
46-
ar.approve(access_level=gitlab.MAINTAINER_ACCESS) # explicitly set access level
46+
ar.approve(access_level=gitlab.const.MAINTAINER_ACCESS) # explicitly set access level
4747

4848
Deny (delete) an access request::
4949

docs/gl_objects/groups.rst

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Remove a group::
8080

8181
Share/unshare the group with a group::
8282

83-
group.share(group2.id, gitlab.DEVELOPER_ACCESS)
83+
group.share(group2.id, gitlab.const.DEVELOPER_ACCESS)
8484
group.unshare(group2.id)
8585

8686
Import / Export
@@ -237,11 +237,11 @@ Group members
237237

238238
The following constants define the supported access levels:
239239

240-
* ``gitlab.GUEST_ACCESS = 10``
241-
* ``gitlab.REPORTER_ACCESS = 20``
242-
* ``gitlab.DEVELOPER_ACCESS = 30``
243-
* ``gitlab.MAINTAINER_ACCESS = 40``
244-
* ``gitlab.OWNER_ACCESS = 50``
240+
* ``gitlab.const.GUEST_ACCESS = 10``
241+
* ``gitlab.const.REPORTER_ACCESS = 20``
242+
* ``gitlab.const.DEVELOPER_ACCESS = 30``
243+
* ``gitlab.const.MAINTAINER_ACCESS = 40``
244+
* ``gitlab.const.OWNER_ACCESS = 50``
245245

246246
Reference
247247
---------
@@ -284,11 +284,11 @@ Get a member of a group, including members inherited through ancestor groups::
284284
Add a member to the group::
285285

286286
member = group.members.create({'user_id': user_id,
287-
'access_level': gitlab.GUEST_ACCESS})
287+
'access_level': gitlab.const.GUEST_ACCESS})
288288

289289
Update a member (change the access level)::
290290

291-
member.access_level = gitlab.DEVELOPER_ACCESS
291+
member.access_level = gitlab.const.DEVELOPER_ACCESS
292292
member.save()
293293

294294
Remove a member from the group::
@@ -316,7 +316,7 @@ LDAP group links
316316

317317
Add an LDAP group link to an existing GitLab group::
318318

319-
group.add_ldap_group_link(ldap_group_cn, gitlab.DEVELOPER_ACCESS, 'ldapmain')
319+
group.add_ldap_group_link(ldap_group_cn, gitlab.const.DEVELOPER_ACCESS, 'ldapmain')
320320

321321
Remove a link::
322322

docs/gl_objects/notifications.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ Notification settings
55
You can define notification settings globally, for groups and for projects.
66
Valid levels are defined as constants:
77

8-
* ``gitlab.NOTIFICATION_LEVEL_DISABLED``
9-
* ``gitlab.NOTIFICATION_LEVEL_PARTICIPATING``
10-
* ``gitlab.NOTIFICATION_LEVEL_WATCH``
11-
* ``gitlab.NOTIFICATION_LEVEL_GLOBAL``
12-
* ``gitlab.NOTIFICATION_LEVEL_MENTION``
13-
* ``gitlab.NOTIFICATION_LEVEL_CUSTOM``
8+
* ``gitlab.const.NOTIFICATION_LEVEL_DISABLED``
9+
* ``gitlab.const.NOTIFICATION_LEVEL_PARTICIPATING``
10+
* ``gitlab.const.NOTIFICATION_LEVEL_WATCH``
11+
* ``gitlab.const.NOTIFICATION_LEVEL_GLOBAL``
12+
* ``gitlab.const.NOTIFICATION_LEVEL_MENTION``
13+
* ``gitlab.const.NOTIFICATION_LEVEL_CUSTOM``
1414

1515
You get access to fine-grained settings if you use the
1616
``NOTIFICATION_LEVEL_CUSTOM`` level.
@@ -47,10 +47,10 @@ Get the notifications settings::
4747
Update the notifications settings::
4848

4949
# use a predefined level
50-
settings.level = gitlab.NOTIFICATION_LEVEL_WATCH
50+
settings.level = gitlab.const.NOTIFICATION_LEVEL_WATCH
5151

5252
# create a custom setup
53-
settings.level = gitlab.NOTIFICATION_LEVEL_CUSTOM
53+
settings.level = gitlab.const.NOTIFICATION_LEVEL_CUSTOM
5454
settings.save() # will create additional attributes, but not mandatory
5555

5656
settings.new_merge_request = True

docs/gl_objects/projects.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,9 @@ Project snippets
439439

440440
The snippet visibility can be defined using the following constants:
441441

442-
* ``gitlab.VISIBILITY_PRIVATE``
443-
* ``gitlab.VISIBILITY_INTERNAL``
444-
* ``gitlab.VISIBILITY_PUBLIC``
442+
* ``gitlab.const.VISIBILITY_PRIVATE``
443+
* ``gitlab.const.VISIBILITY_INTERNAL``
444+
* ``gitlab.const.VISIBILITY_PUBLIC``
445445

446446
Reference
447447
---------
@@ -480,7 +480,7 @@ Create a snippet::
480480
'file_name': 'foo.py',
481481
'code': 'import gitlab',
482482
'visibility_level':
483-
gitlab.VISIBILITY_PRIVATE})
483+
gitlab.const.VISIBILITY_PRIVATE})
484484

485485
Update a snippet::
486486

@@ -546,11 +546,11 @@ Get a member of a project, including members inherited through ancestor groups::
546546
Add a project member::
547547

548548
member = project.members.create({'user_id': user.id, 'access_level':
549-
gitlab.DEVELOPER_ACCESS})
549+
gitlab.const.DEVELOPER_ACCESS})
550550

551551
Modify a project member (change the access level)::
552552

553-
member.access_level = gitlab.MAINTAINER_ACCESS
553+
member.access_level = gitlab.const.MAINTAINER_ACCESS
554554
member.save()
555555

556556
Remove a member from the project team::
@@ -561,7 +561,7 @@ Remove a member from the project team::
561561

562562
Share/unshare the project with a group::
563563

564-
project.share(group.id, gitlab.DEVELOPER_ACCESS)
564+
project.share(group.id, gitlab.const.DEVELOPER_ACCESS)
565565
project.unshare(group.id)
566566

567567
Project hooks

docs/gl_objects/protected_branches.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ Create a protected branch::
3131

3232
p_branch = project.protectedbranches.create({
3333
'name': '*-stable',
34-
'merge_access_level': gitlab.DEVELOPER_ACCESS,
35-
'push_access_level': gitlab.MAINTAINER_ACCESS
34+
'merge_access_level': gitlab.const.DEVELOPER_ACCESS,
35+
'push_access_level': gitlab.const.MAINTAINER_ACCESS
3636
})
3737

3838
Create a protected branch with more granular access control::
@@ -41,7 +41,7 @@ Create a protected branch with more granular access control::
4141
'name': '*-stable',
4242
'allowed_to_push': [{"user_id": 99}, {"user_id": 98}],
4343
'allowed_to_merge': [{"group_id": 653}],
44-
'allowed_to_unprotect': [{"access_level": gitlab.MAINTAINER_ACCESS}]
44+
'allowed_to_unprotect': [{"access_level": gitlab.const.MAINTAINER_ACCESS}]
4545
})
4646

4747
Delete a protected branch::

docs/gl_objects/search.rst

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,24 @@ string. The following constants are provided to represent the possible scopes:
99

1010
* Shared scopes (global, group and project):
1111

12-
+ ``gitlab.SEARCH_SCOPE_PROJECTS``: ``projects``
13-
+ ``gitlab.SEARCH_SCOPE_ISSUES``: ``issues``
14-
+ ``gitlab.SEARCH_SCOPE_MERGE_REQUESTS``: ``merge_requests``
15-
+ ``gitlab.SEARCH_SCOPE_MILESTONES``: ``milestones``
16-
+ ``gitlab.SEARCH_SCOPE_WIKI_BLOBS``: ``wiki_blobs``
17-
+ ``gitlab.SEARCH_SCOPE_COMMITS``: ``commits``
18-
+ ``gitlab.SEARCH_SCOPE_BLOBS``: ``blobs``
19-
+ ``gitlab.SEARCH_SCOPE_USERS``: ``users``
12+
+ ``gitlab.const.SEARCH_SCOPE_PROJECTS``: ``projects``
13+
+ ``gitlab.const.SEARCH_SCOPE_ISSUES``: ``issues``
14+
+ ``gitlab.const.SEARCH_SCOPE_MERGE_REQUESTS``: ``merge_requests``
15+
+ ``gitlab.const.SEARCH_SCOPE_MILESTONES``: ``milestones``
16+
+ ``gitlab.const.SEARCH_SCOPE_WIKI_BLOBS``: ``wiki_blobs``
17+
+ ``gitlab.const.SEARCH_SCOPE_COMMITS``: ``commits``
18+
+ ``gitlab.const.SEARCH_SCOPE_BLOBS``: ``blobs``
19+
+ ``gitlab.const.SEARCH_SCOPE_USERS``: ``users``
2020

2121

2222
* specific global scope:
2323

24-
+ ``gitlab.SEARCH_SCOPE_GLOBAL_SNIPPET_TITLES``: ``snippet_titles``
24+
+ ``gitlab.const.SEARCH_SCOPE_GLOBAL_SNIPPET_TITLES``: ``snippet_titles``
2525

2626

2727
* specific project scope:
2828

29-
+ ``gitlab.SEARCH_SCOPE_PROJECT_NOTES``: ``notes``
29+
+ ``gitlab.const.SEARCH_SCOPE_PROJECT_NOTES``: ``notes``
3030

3131

3232
Reference
@@ -46,30 +46,30 @@ Examples
4646
Search for issues matching a specific string::
4747

4848
# global search
49-
gl.search(gitlab.SEARCH_SCOPE_ISSUES, 'regression')
49+
gl.search(gitlab.const.SEARCH_SCOPE_ISSUES, 'regression')
5050

5151
# group search
5252
group = gl.groups.get('mygroup')
53-
group.search(gitlab.SEARCH_SCOPE_ISSUES, 'regression')
53+
group.search(gitlab.const.SEARCH_SCOPE_ISSUES, 'regression')
5454

5555
# project search
5656
project = gl.projects.get('myproject')
57-
project.search(gitlab.SEARCH_SCOPE_ISSUES, 'regression')
57+
project.search(gitlab.const.SEARCH_SCOPE_ISSUES, 'regression')
5858

5959
The ``search()`` methods implement the pagination support::
6060

6161
# get lists of 10 items, and start at page 2
62-
gl.search(gitlab.SEARCH_SCOPE_ISSUES, search_str, page=2, per_page=10)
62+
gl.search(gitlab.const.SEARCH_SCOPE_ISSUES, search_str, page=2, per_page=10)
6363

6464
# get a generator that will automatically make required API calls for
6565
# pagination
66-
for item in gl.search(gitlab.SEARCH_SCOPE_ISSUES, search_str, as_list=False):
66+
for item in gl.search(gitlab.const.SEARCH_SCOPE_ISSUES, search_str, as_list=False):
6767
do_something(item)
6868

6969
The search API doesn't return objects, but dicts. If you need to act on
7070
objects, you need to create them explicitly::
7171

72-
for item in gl.search(gitlab.SEARCH_SCOPE_ISSUES, search_str, as_list=False):
72+
for item in gl.search(gitlab.const.SEARCH_SCOPE_ISSUES, search_str, as_list=False):
7373
issue_project = gl.projects.get(item['project_id'], lazy=True)
7474
issue = issue_project.issues.get(item['iid'])
7575
issue.state = 'closed'

docs/gl_objects/snippets.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Create a snippet::
4444

4545
Update the snippet attributes::
4646

47-
snippet.visibility_level = gitlab.VISIBILITY_PUBLIC
47+
snippet.visibility_level = gitlab.const.VISIBILITY_PUBLIC
4848
snippet.save()
4949

5050
To update a snippet code you need to create a ``ProjectSnippet`` object::

gitlab/__init__.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"""Wrapper for the GitLab API."""
1818

1919
import warnings
20+
from typing import Any
2021

2122
import gitlab.config # noqa: F401
2223
from gitlab.__version__ import ( # noqa: F401
@@ -28,7 +29,22 @@
2829
__version__,
2930
)
3031
from gitlab.client import Gitlab, GitlabList # noqa: F401
31-
from gitlab.const import * # noqa: F401,F403
3232
from gitlab.exceptions import * # noqa: F401,F403
3333

3434
warnings.filterwarnings("default", category=DeprecationWarning, module="^gitlab")
35+
36+
37+
# NOTE(jlvillal): We are deprecating access to the gitlab.const values which
38+
# were previously imported into this namespace by the
39+
# 'from gitlab.const import *' statement.
40+
def __getattr__(name: str) -> Any:
41+
# Deprecate direct access to constants without namespace
42+
if name in gitlab.const._DEPRECATED:
43+
warnings.warn(
44+
f"\nDirect access to 'gitlab.{name}' is deprecated and will be "
45+
f"removed in a future major python-gitlab release. Please "
46+
f"use 'gitlab.const.{name}' instead.",
47+
DeprecationWarning,
48+
)
49+
return getattr(gitlab.const, name)
50+
raise AttributeError(f"module {__name__} has no attribute {name}")

gitlab/const.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,41 @@
1717

1818
from gitlab.__version__ import __title__, __version__
1919

20+
# NOTE(jlvillal): '_DEPRECATED' only affects users accessing constants via the
21+
# top-level gitlab.* namespace. See 'gitlab/__init__.py:__getattr__()' for the
22+
# consumer of '_DEPRECATED' For example 'x = gitlab.NO_ACCESS'. We want users
23+
# to instead use constants by doing code like: gitlab.const.NO_ACCESS.
24+
_DEPRECATED = [
25+
"DEFAULT_URL",
26+
"DEVELOPER_ACCESS",
27+
"GUEST_ACCESS",
28+
"MAINTAINER_ACCESS",
29+
"MINIMAL_ACCESS",
30+
"NO_ACCESS",
31+
"NOTIFICATION_LEVEL_CUSTOM",
32+
"NOTIFICATION_LEVEL_DISABLED",
33+
"NOTIFICATION_LEVEL_GLOBAL",
34+
"NOTIFICATION_LEVEL_MENTION",
35+
"NOTIFICATION_LEVEL_PARTICIPATING",
36+
"NOTIFICATION_LEVEL_WATCH",
37+
"OWNER_ACCESS",
38+
"REPORTER_ACCESS",
39+
"SEARCH_SCOPE_BLOBS",
40+
"SEARCH_SCOPE_COMMITS",
41+
"SEARCH_SCOPE_GLOBAL_SNIPPET_TITLES",
42+
"SEARCH_SCOPE_ISSUES",
43+
"SEARCH_SCOPE_MERGE_REQUESTS",
44+
"SEARCH_SCOPE_MILESTONES",
45+
"SEARCH_SCOPE_PROJECT_NOTES",
46+
"SEARCH_SCOPE_PROJECTS",
47+
"SEARCH_SCOPE_USERS",
48+
"SEARCH_SCOPE_WIKI_BLOBS",
49+
"USER_AGENT",
50+
"VISIBILITY_INTERNAL",
51+
"VISIBILITY_PRIVATE",
52+
"VISIBILITY_PUBLIC",
53+
]
54+
2055
DEFAULT_URL: str = "https://gitlab.com"
2156

2257
NO_ACCESS: int = 0

gitlab/mixins.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ class AccessRequestMixin(_RestObjectBase):
618618
)
619619
@exc.on_http_error(exc.GitlabUpdateError)
620620
def approve(
621-
self, access_level: int = gitlab.DEVELOPER_ACCESS, **kwargs: Any
621+
self, access_level: int = gitlab.const.DEVELOPER_ACCESS, **kwargs: Any
622622
) -> None:
623623
"""Approve an access request.
624624

tests/functional/api/test_gitlab.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ def test_namespaces(gl):
118118

119119
def test_notification_settings(gl):
120120
settings = gl.notificationsettings.get()
121-
settings.level = gitlab.NOTIFICATION_LEVEL_WATCH
121+
settings.level = gitlab.const.NOTIFICATION_LEVEL_WATCH
122122
settings.save()
123123

124124
settings = gl.notificationsettings.get()
125-
assert settings.level == gitlab.NOTIFICATION_LEVEL_WATCH
125+
assert settings.level == gitlab.const.NOTIFICATION_LEVEL_WATCH
126126

127127

128128
def test_user_activities(gl):

tests/functional/api/test_snippets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def test_project_snippets(project):
3333
"title": "snip1",
3434
"file_name": "foo.py",
3535
"content": "initial content",
36-
"visibility": gitlab.VISIBILITY_PRIVATE,
36+
"visibility": gitlab.const.VISIBILITY_PRIVATE,
3737
}
3838
)
3939

tests/unit/test_config.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222

2323
import pytest
2424

25-
from gitlab import config, USER_AGENT
25+
import gitlab
26+
from gitlab import config
2627

2728
custom_user_agent = "my-package/1.0.0"
2829

@@ -252,7 +253,7 @@ def test_data_from_helper(m_open, path_exists, tmp_path):
252253
@pytest.mark.parametrize(
253254
"config_string,expected_agent",
254255
[
255-
(valid_config, USER_AGENT),
256+
(valid_config, gitlab.const.USER_AGENT),
256257
(custom_user_agent_config, custom_user_agent),
257258
],
258259
)

0 commit comments

Comments
 (0)