Skip to content

Commit b07eece

Browse files
chore: replace usage of utils._url_encode() with utils.EncodedId()
utils.EncodedId() has basically the same functionalityy of using utils._url_encode(). So remove utils._url_encode() as we don't need it.
1 parent a2e7c38 commit b07eece

File tree

9 files changed

+28
-113
lines changed

9 files changed

+28
-113
lines changed

gitlab/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ def encoded_id(self) -> Any:
223223
path"""
224224
obj_id = self.get_id()
225225
if isinstance(obj_id, str):
226-
obj_id = gitlab.utils._url_encode(obj_id)
226+
obj_id = gitlab.utils.EncodedId(obj_id)
227227
return obj_id
228228

229229
@property

gitlab/mixins.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ def get(
9999
GitlabAuthenticationError: If authentication is not correct
100100
GitlabGetError: If the server cannot perform the request
101101
"""
102-
id = utils._url_encode(id)
102+
if isinstance(id, str):
103+
id = utils.EncodedId(id)
103104
path = f"{self.path}/{id}"
104105
if TYPE_CHECKING:
105106
assert self._obj_cls is not None
@@ -390,7 +391,7 @@ def update(
390391
if id is None:
391392
path = self.path
392393
else:
393-
path = f"{self.path}/{utils._url_encode(id)}"
394+
path = f"{self.path}/{utils.EncodedId(id)}"
394395

395396
self._check_missing_update_attrs(new_data)
396397
files = {}
@@ -443,7 +444,7 @@ def set(self, key: str, value: str, **kwargs: Any) -> base.RESTObject:
443444
Returns:
444445
The created/updated attribute
445446
"""
446-
path = f"{self.path}/{utils._url_encode(key)}"
447+
path = f"{self.path}/{utils.EncodedId(key)}"
447448
data = {"value": value}
448449
server_data = self.gitlab.http_put(path, post_data=data, **kwargs)
449450
if TYPE_CHECKING:
@@ -476,7 +477,7 @@ def delete(self, id: Union[str, int], **kwargs: Any) -> None:
476477
if id is None:
477478
path = self.path
478479
else:
479-
path = f"{self.path}/{utils._url_encode(id)}"
480+
path = f"{self.path}/{utils.EncodedId(id)}"
480481
self.gitlab.http_delete(path, **kwargs)
481482

482483

gitlab/utils.py

Lines changed: 10 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1717

1818
import urllib.parse
19-
from typing import Any, Callable, Dict, Optional, overload, Union
19+
from typing import Any, Callable, Dict, Optional, Union
2020

2121
import requests
2222

@@ -71,83 +71,18 @@ class EncodedId(str):
7171
https://docs.gitlab.com/ee/api/index.html#path-parameters
7272
"""
7373

74-
# `original_str` will contain the original string value that was used to create the
75-
# first instance of EncodedId. We will use this original value to generate the
76-
# URL-encoded value each time.
77-
original_str: str
78-
79-
def __new__(cls, value: Union[str, int, "EncodedId"]) -> "EncodedId":
80-
# __new__() gets called before __init__()
81-
if isinstance(value, int):
82-
value = str(value)
83-
# Make sure isinstance() for `EncodedId` comes before check for `str` as
84-
# `EncodedId` is an instance of `str` and would pass that check.
85-
elif isinstance(value, EncodedId):
86-
# We use the original string value to URL-encode
87-
value = value.original_str
88-
elif isinstance(value, str):
89-
pass
90-
else:
91-
raise ValueError(f"Unsupported type received: {type(value)}")
92-
# Set the value our string will return
74+
# mypy complains if return type other than the class type. So we ignore issue.
75+
def __new__( # type: ignore
76+
cls, value: Union[str, int, "EncodedId"]
77+
) -> Union[int, "EncodedId"]:
78+
if isinstance(value, (int, EncodedId)):
79+
return value
80+
81+
if not isinstance(value, str):
82+
raise TypeError(f"Unsupported type received: {type(value)}")
9383
value = urllib.parse.quote(value, safe="")
9484
return super().__new__(cls, value)
9585

96-
def __init__(self, value: Union[int, str]) -> None:
97-
# At this point `super().__str__()` returns the URL-encoded value. Which means
98-
# when using this as a `str` it will return the URL-encoded value.
99-
#
100-
# But `value` contains the original value passed in `EncodedId(value)`. We use
101-
# this to always keep the original string that was received so that no matter
102-
# how many times we recurse we only URL-encode our original string once.
103-
if isinstance(value, int):
104-
value = str(value)
105-
# Make sure isinstance() for `EncodedId` comes before check for `str` as
106-
# `EncodedId` is an instance of `str` and would pass that check.
107-
elif isinstance(value, EncodedId):
108-
# This is the key part as we are always keeping the original string even
109-
# through multiple recursions.
110-
value = value.original_str
111-
elif isinstance(value, str):
112-
pass
113-
else:
114-
raise ValueError(f"Unsupported type received: {type(value)}")
115-
self.original_str = value
116-
super().__init__()
117-
118-
119-
@overload
120-
def _url_encode(id: int) -> int:
121-
...
122-
123-
124-
@overload
125-
def _url_encode(id: Union[str, EncodedId]) -> EncodedId:
126-
...
127-
128-
129-
def _url_encode(id: Union[int, str, EncodedId]) -> Union[int, EncodedId]:
130-
"""Encode/quote the characters in the string so that they can be used in a path.
131-
132-
Reference to documentation on why this is necessary.
133-
134-
https://docs.gitlab.com/ee/api/index.html#namespaced-path-encoding
135-
136-
If using namespaced API requests, make sure that the NAMESPACE/PROJECT_PATH is
137-
URL-encoded. For example, / is represented by %2F
138-
139-
https://docs.gitlab.com/ee/api/index.html#path-parameters
140-
141-
Path parameters that are required to be URL-encoded must be followed. If not, it
142-
doesn’t match an API endpoint and responds with a 404. If there’s something in front
143-
of the API (for example, Apache), ensure that it doesn’t decode the URL-encoded path
144-
parameters.
145-
146-
"""
147-
if isinstance(id, (int, EncodedId)):
148-
return id
149-
return EncodedId(id)
150-
15186

15287
def remove_none_from_dict(data: Dict[str, Any]) -> Dict[str, Any]:
15388
return {k: v for k, v in data.items() if v is not None}

gitlab/v4/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def _process_from_parent_attrs(self) -> None:
7575
if key not in self.args:
7676
continue
7777

78-
self.parent_args[key] = gitlab.utils._url_encode(self.args[key])
78+
self.parent_args[key] = gitlab.utils.EncodedId(self.args[key])
7979
# If we don't delete it then it will be added to the URL as a query-string
8080
del self.args[key]
8181

gitlab/v4/objects/features.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def set(
5252
Returns:
5353
The created/updated attribute
5454
"""
55-
name = utils._url_encode(name)
55+
name = utils.EncodedId(name)
5656
path = f"{self.path}/{name}"
5757
data = {
5858
"value": value,

gitlab/v4/objects/files.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def save( # type: ignore
5656
"""
5757
self.branch = branch
5858
self.commit_message = commit_message
59-
self.file_path = utils._url_encode(self.file_path)
59+
self.file_path = utils.EncodedId(self.file_path)
6060
super(ProjectFile, self).save(**kwargs)
6161

6262
@exc.on_http_error(exc.GitlabDeleteError)
@@ -144,7 +144,7 @@ def create(
144144
assert data is not None
145145
self._check_missing_create_attrs(data)
146146
new_data = data.copy()
147-
file_path = utils._url_encode(new_data.pop("file_path"))
147+
file_path = utils.EncodedId(new_data.pop("file_path"))
148148
path = f"{self.path}/{file_path}"
149149
server_data = self.gitlab.http_post(path, post_data=new_data, **kwargs)
150150
if TYPE_CHECKING:
@@ -173,7 +173,7 @@ def update( # type: ignore
173173
"""
174174
new_data = new_data or {}
175175
data = new_data.copy()
176-
file_path = utils._url_encode(file_path)
176+
file_path = utils.EncodedId(file_path)
177177
data["file_path"] = file_path
178178
path = f"{self.path}/{file_path}"
179179
self._check_missing_update_attrs(data)
@@ -203,7 +203,7 @@ def delete( # type: ignore
203203
GitlabAuthenticationError: If authentication is not correct
204204
GitlabDeleteError: If the server cannot perform the request
205205
"""
206-
file_path = utils._url_encode(file_path)
206+
file_path = utils.EncodedId(file_path)
207207
path = f"{self.path}/{file_path}"
208208
data = {"branch": branch, "commit_message": commit_message}
209209
self.gitlab.http_delete(path, query_data=data, **kwargs)
@@ -239,7 +239,7 @@ def raw(
239239
Returns:
240240
The file content
241241
"""
242-
file_path = utils._url_encode(file_path)
242+
file_path = utils.EncodedId(file_path)
243243
path = f"{self.path}/{file_path}/raw"
244244
query_data = {"ref": ref}
245245
result = self.gitlab.http_get(
@@ -266,7 +266,7 @@ def blame(self, file_path: str, ref: str, **kwargs: Any) -> List[Dict[str, Any]]
266266
Returns:
267267
A list of commits/lines matching the file
268268
"""
269-
file_path = utils._url_encode(file_path)
269+
file_path = utils.EncodedId(file_path)
270270
path = f"{self.path}/{file_path}/blame"
271271
query_data = {"ref": ref}
272272
result = self.gitlab.http_list(path, query_data, **kwargs)

gitlab/v4/objects/repositories.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def update_submodule(
3939
GitlabPutError: If the submodule could not be updated
4040
"""
4141

42-
submodule = utils._url_encode(submodule)
42+
submodule = utils.EncodedId(submodule)
4343
path = f"/projects/{self.encoded_id}/repository/submodules/{submodule}"
4444
data = {"branch": branch, "commit_sha": commit_sha}
4545
if "commit_message" in kwargs:

tests/functional/api/test_lazy_objects.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def lazy_project(gl, project):
1212
def test_lazy_id(project, lazy_project):
1313
assert isinstance(lazy_project.id, str)
1414
assert isinstance(lazy_project.id, gitlab.utils.EncodedId)
15-
assert lazy_project.id == gitlab.utils._url_encode(project.path_with_namespace)
15+
assert lazy_project.id == gitlab.utils.EncodedId(project.path_with_namespace)
1616

1717

1818
def test_refresh_after_lazy_get_with_path(project, lazy_project):

tests/unit/test_utils.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,10 @@
2020
from gitlab import utils
2121

2222

23-
def test_url_encode():
24-
src = "nothing_special"
25-
dest = "nothing_special"
26-
assert dest == utils._url_encode(src)
27-
28-
src = "foo#bar/baz/"
29-
dest = "foo%23bar%2Fbaz%2F"
30-
assert dest == utils._url_encode(src)
31-
32-
src = "foo%bar/baz/"
33-
dest = "foo%25bar%2Fbaz%2F"
34-
assert dest == utils._url_encode(src)
35-
36-
# periods/dots should not be modified
37-
src = "docs/README.md"
38-
dest = "docs%2FREADME.md"
39-
assert dest == utils._url_encode(src)
40-
41-
4223
class TestEncodedId:
4324
def test_init_str(self):
4425
obj = utils.EncodedId("Hello")
26+
assert "Hello" == obj
4527
assert "Hello" == str(obj)
4628
assert "Hello" == f"{obj}"
4729

@@ -51,6 +33,7 @@ def test_init_str(self):
5133

5234
def test_init_int(self):
5335
obj = utils.EncodedId(23)
36+
assert 23 == obj
5437
assert "23" == str(obj)
5538
assert "23" == f"{obj}"
5639

@@ -60,12 +43,10 @@ def test_init_encodeid_str(self):
6043
obj = utils.EncodedId(obj_init)
6144
assert value == str(obj)
6245
assert value == f"{obj}"
63-
assert value == obj.original_str
6446

6547
value = "we got/a/path"
6648
expected = "we%20got%2Fa%2Fpath"
6749
obj_init = utils.EncodedId(value)
68-
assert value == obj_init.original_str
6950
assert expected == str(obj_init)
7051
assert expected == f"{obj_init}"
7152
# Show that no matter how many times we recursively call it we still only
@@ -75,8 +56,6 @@ def test_init_encodeid_str(self):
7556
)
7657
assert expected == str(obj)
7758
assert expected == f"{obj}"
78-
# We have stored a copy of our original string
79-
assert value == obj.original_str
8059

8160
# Show assignments still only encode once
8261
obj2 = obj

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy