| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent a2e7c38 commit b07eece
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -223,7 +223,7 @@ def encoded_id(self) -> Any: | |||
| 223 | 223 | path""" | |
| 224 | 224 | obj_id = self.get_id() | |
| 225 | 225 | if isinstance(obj_id, str): | |
| 226 | - obj_id = gitlab.utils._url_encode(obj_id) | ||
| 226 | + obj_id = gitlab.utils.EncodedId(obj_id) | ||
| 227 | 227 | return obj_id | |
| 228 | 228 | ||
| 229 | 229 | @property | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -99,7 +99,8 @@ def get( | |||
| 99 | 99 | GitlabAuthenticationError: If authentication is not correct | |
| 100 | 100 | GitlabGetError: If the server cannot perform the request | |
| 101 | 101 | """ | |
| 102 | - id = utils._url_encode(id) | ||
| 102 | + if isinstance(id, str): | ||
| 103 | + id = utils.EncodedId(id) | ||
| 103 | 104 | path = f"{self.path}/{id}" | |
| 104 | 105 | if TYPE_CHECKING: | |
| 105 | 106 | assert self._obj_cls is not None | |
@@ -390,7 +391,7 @@ def update( | |||
| 390 | 391 | if id is None: | |
| 391 | 392 | path = self.path | |
| 392 | 393 | else: | |
| 393 | - path = f"{self.path}/{utils._url_encode(id)}" | ||
| 394 | + path = f"{self.path}/{utils.EncodedId(id)}" | ||
| 394 | 395 | ||
| 395 | 396 | self._check_missing_update_attrs(new_data) | |
| 396 | 397 | files = {} | |
@@ -443,7 +444,7 @@ def set(self, key: str, value: str, **kwargs: Any) -> base.RESTObject: | |||
| 443 | 444 | Returns: | |
| 444 | 445 | The created/updated attribute | |
| 445 | 446 | """ | |
| 446 | - path = f"{self.path}/{utils._url_encode(key)}" | ||
| 447 | + path = f"{self.path}/{utils.EncodedId(key)}" | ||
| 447 | 448 | data = {"value": value} | |
| 448 | 449 | server_data = self.gitlab.http_put(path, post_data=data, **kwargs) | |
| 449 | 450 | if TYPE_CHECKING: | |
@@ -476,7 +477,7 @@ def delete(self, id: Union[str, int], **kwargs: Any) -> None: | |||
| 476 | 477 | if id is None: | |
| 477 | 478 | path = self.path | |
| 478 | 479 | else: | |
| 479 | - path = f"{self.path}/{utils._url_encode(id)}" | ||
| 480 | + path = f"{self.path}/{utils.EncodedId(id)}" | ||
| 480 | 481 | self.gitlab.http_delete(path, **kwargs) | |
| 481 | 482 | ||
| 482 | 483 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,7 +16,7 @@ | |||
| 16 | 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 17 | 17 | ||
| 18 | 18 | import urllib.parse | |
| 19 | - from typing import Any, Callable, Dict, Optional, overload, Union | ||
| 19 | + from typing import Any, Callable, Dict, Optional, Union | ||
| 20 | 20 | ||
| 21 | 21 | import requests | |
| 22 | 22 | ||
@@ -71,83 +71,18 @@ class EncodedId(str): | |||
| 71 | 71 | https://docs.gitlab.com/ee/api/index.html#path-parameters | |
| 72 | 72 | """ | |
| 73 | 73 | ||
| 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)}") | ||
| 93 | 83 | value = urllib.parse.quote(value, safe="") | |
| 94 | 84 | return super().__new__(cls, value) | |
| 95 | 85 | ||
| 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 | - | ||
| 151 | 86 | ||
| 152 | 87 | def remove_none_from_dict(data: Dict[str, Any]) -> Dict[str, Any]: | |
| 153 | 88 | return {k: v for k, v in data.items() if v is not None} | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -75,7 +75,7 @@ def _process_from_parent_attrs(self) -> None: | |||
| 75 | 75 | if key not in self.args: | |
| 76 | 76 | continue | |
| 77 | 77 | ||
| 78 | - self.parent_args[key] = gitlab.utils._url_encode(self.args[key]) | ||
| 78 | + self.parent_args[key] = gitlab.utils.EncodedId(self.args[key]) | ||
| 79 | 79 | # If we don't delete it then it will be added to the URL as a query-string | |
| 80 | 80 | del self.args[key] | |
| 81 | 81 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -52,7 +52,7 @@ def set( | |||
| 52 | 52 | Returns: | |
| 53 | 53 | The created/updated attribute | |
| 54 | 54 | """ | |
| 55 | - name = utils._url_encode(name) | ||
| 55 | + name = utils.EncodedId(name) | ||
| 56 | 56 | path = f"{self.path}/{name}" | |
| 57 | 57 | data = { | |
| 58 | 58 | "value": value, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -56,7 +56,7 @@ def save( # type: ignore | |||
| 56 | 56 | """ | |
| 57 | 57 | self.branch = branch | |
| 58 | 58 | self.commit_message = commit_message | |
| 59 | - self.file_path = utils._url_encode(self.file_path) | ||
| 59 | + self.file_path = utils.EncodedId(self.file_path) | ||
| 60 | 60 | super(ProjectFile, self).save(**kwargs) | |
| 61 | 61 | ||
| 62 | 62 | @exc.on_http_error(exc.GitlabDeleteError) | |
@@ -144,7 +144,7 @@ def create( | |||
| 144 | 144 | assert data is not None | |
| 145 | 145 | self._check_missing_create_attrs(data) | |
| 146 | 146 | 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")) | ||
| 148 | 148 | path = f"{self.path}/{file_path}" | |
| 149 | 149 | server_data = self.gitlab.http_post(path, post_data=new_data, **kwargs) | |
| 150 | 150 | if TYPE_CHECKING: | |
@@ -173,7 +173,7 @@ def update( # type: ignore | |||
| 173 | 173 | """ | |
| 174 | 174 | new_data = new_data or {} | |
| 175 | 175 | data = new_data.copy() | |
| 176 | - file_path = utils._url_encode(file_path) | ||
| 176 | + file_path = utils.EncodedId(file_path) | ||
| 177 | 177 | data["file_path"] = file_path | |
| 178 | 178 | path = f"{self.path}/{file_path}" | |
| 179 | 179 | self._check_missing_update_attrs(data) | |
@@ -203,7 +203,7 @@ def delete( # type: ignore | |||
| 203 | 203 | GitlabAuthenticationError: If authentication is not correct | |
| 204 | 204 | GitlabDeleteError: If the server cannot perform the request | |
| 205 | 205 | """ | |
| 206 | - file_path = utils._url_encode(file_path) | ||
| 206 | + file_path = utils.EncodedId(file_path) | ||
| 207 | 207 | path = f"{self.path}/{file_path}" | |
| 208 | 208 | data = {"branch": branch, "commit_message": commit_message} | |
| 209 | 209 | self.gitlab.http_delete(path, query_data=data, **kwargs) | |
@@ -239,7 +239,7 @@ def raw( | |||
| 239 | 239 | Returns: | |
| 240 | 240 | The file content | |
| 241 | 241 | """ | |
| 242 | - file_path = utils._url_encode(file_path) | ||
| 242 | + file_path = utils.EncodedId(file_path) | ||
| 243 | 243 | path = f"{self.path}/{file_path}/raw" | |
| 244 | 244 | query_data = {"ref": ref} | |
| 245 | 245 | result = self.gitlab.http_get( | |
@@ -266,7 +266,7 @@ def blame(self, file_path: str, ref: str, **kwargs: Any) -> List[Dict[str, Any]] | |||
| 266 | 266 | Returns: | |
| 267 | 267 | A list of commits/lines matching the file | |
| 268 | 268 | """ | |
| 269 | - file_path = utils._url_encode(file_path) | ||
| 269 | + file_path = utils.EncodedId(file_path) | ||
| 270 | 270 | path = f"{self.path}/{file_path}/blame" | |
| 271 | 271 | query_data = {"ref": ref} | |
| 272 | 272 | result = self.gitlab.http_list(path, query_data, **kwargs) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,7 +39,7 @@ def update_submodule( | |||
| 39 | 39 | GitlabPutError: If the submodule could not be updated | |
| 40 | 40 | """ | |
| 41 | 41 | ||
| 42 | - submodule = utils._url_encode(submodule) | ||
| 42 | + submodule = utils.EncodedId(submodule) | ||
| 43 | 43 | path = f"/projects/{self.encoded_id}/repository/submodules/{submodule}" | |
| 44 | 44 | data = {"branch": branch, "commit_sha": commit_sha} | |
| 45 | 45 | if "commit_message" in kwargs: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,7 +12,7 @@ def lazy_project(gl, project): | |||
| 12 | 12 | def test_lazy_id(project, lazy_project): | |
| 13 | 13 | assert isinstance(lazy_project.id, str) | |
| 14 | 14 | 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) | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | def test_refresh_after_lazy_get_with_path(project, lazy_project): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,28 +20,10 @@ | |||
| 20 | 20 | from gitlab import utils | |
| 21 | 21 | ||
| 22 | 22 | ||
| 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 | - | ||
| 42 | 23 | class TestEncodedId: | |
| 43 | 24 | def test_init_str(self): | |
| 44 | 25 | obj = utils.EncodedId("Hello") | |
| 26 | + assert "Hello" == obj | ||
| 45 | 27 | assert "Hello" == str(obj) | |
| 46 | 28 | assert "Hello" == f"{obj}" | |
| 47 | 29 | ||
@@ -51,6 +33,7 @@ def test_init_str(self): | |||
| 51 | 33 | ||
| 52 | 34 | def test_init_int(self): | |
| 53 | 35 | obj = utils.EncodedId(23) | |
| 36 | + assert 23 == obj | ||
| 54 | 37 | assert "23" == str(obj) | |
| 55 | 38 | assert "23" == f"{obj}" | |
| 56 | 39 | ||
@@ -60,12 +43,10 @@ def test_init_encodeid_str(self): | |||
| 60 | 43 | obj = utils.EncodedId(obj_init) | |
| 61 | 44 | assert value == str(obj) | |
| 62 | 45 | assert value == f"{obj}" | |
| 63 | - assert value == obj.original_str | ||
| 64 | 46 | ||
| 65 | 47 | value = "we got/a/path" | |
| 66 | 48 | expected = "we%20got%2Fa%2Fpath" | |
| 67 | 49 | obj_init = utils.EncodedId(value) | |
| 68 | - assert value == obj_init.original_str | ||
| 69 | 50 | assert expected == str(obj_init) | |
| 70 | 51 | assert expected == f"{obj_init}" | |
| 71 | 52 | # Show that no matter how many times we recursively call it we still only | |
@@ -75,8 +56,6 @@ def test_init_encodeid_str(self): | |||
| 75 | 56 | ) | |
| 76 | 57 | assert expected == str(obj) | |
| 77 | 58 | assert expected == f"{obj}" | |
| 78 | - # We have stored a copy of our original string | ||
| 79 | - assert value == obj.original_str | ||
| 80 | 59 | ||
| 81 | 60 | # Show assignments still only encode once | |
| 82 | 61 | obj2 = obj | |
| Back | FazBrowse Home | New Git URL |
0 commit comments