| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 5e19694 commit 7f71c7a
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,6 +20,7 @@ | |||
| 20 | 20 | from typing import Any | |
| 21 | 21 | ||
| 22 | 22 | import gitlab.config # noqa: F401 | |
| 23 | + from gitlab import utils as _utils | ||
| 23 | 24 | from gitlab._version import ( # noqa: F401 | |
| 24 | 25 | __author__, | |
| 25 | 26 | __copyright__, | |
@@ -40,11 +41,13 @@ | |||
| 40 | 41 | def __getattr__(name: str) -> Any: | |
| 41 | 42 | # Deprecate direct access to constants without namespace | |
| 42 | 43 | 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, | ||
| 44 | + _utils.warn( | ||
| 45 | + message=( | ||
| 46 | + f"\nDirect access to 'gitlab.{name}' is deprecated and will be " | ||
| 47 | + f"removed in a future major python-gitlab release. Please " | ||
| 48 | + f"use 'gitlab.const.{name}' instead." | ||
| 49 | + ), | ||
| 50 | + category=DeprecationWarning, | ||
| 48 | 51 | ) | |
| 49 | 52 | return getattr(gitlab.const, name) | |
| 50 | 53 | raise AttributeError(f"module {__name__} has no attribute {name}") | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,8 +15,11 @@ | |||
| 15 | 15 | # You should have received a copy of the GNU Lesser General Public License | |
| 16 | 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 17 | 17 | ||
| 18 | + import os | ||
| 19 | + import traceback | ||
| 18 | 20 | import urllib.parse | |
| 19 | - from typing import Any, Callable, Dict, Optional, Union | ||
| 21 | + import warnings | ||
| 22 | + from typing import Any, Callable, Dict, Optional, Type, Union | ||
| 20 | 23 | ||
| 21 | 24 | import requests | |
| 22 | 25 | ||
@@ -90,3 +93,30 @@ def __new__( # type: ignore | |||
| 90 | 93 | ||
| 91 | 94 | def remove_none_from_dict(data: Dict[str, Any]) -> Dict[str, Any]: | |
| 92 | 95 | return {k: v for k, v in data.items() if v is not None} | |
| 96 | + | ||
| 97 | + | ||
| 98 | + def warn( | ||
| 99 | + *, | ||
| 100 | + message: str, | ||
| 101 | + category: Optional[Type] = None, | ||
| 102 | + source: Optional[Any] = None, | ||
| 103 | + ) -> None: | ||
| 104 | + """This `warnings.warn` wrapper function attempts to show the location causing the | ||
| 105 | + warning in the user code that called the library. | ||
| 106 | + | ||
| 107 | + It does this by walking up the stack trace to find the first frame located outside | ||
| 108 | + the `gitlab/` directory. This is helpful to users as it shows them their code that | ||
| 109 | + is causing the warning. | ||
| 110 | + """ | ||
| 111 | + # Get `stacklevel` for user code so we indicate where issue is in | ||
| 112 | + # their code. | ||
| 113 | + pg_dir = os.path.abspath(os.path.dirname(__file__)) | ||
| 114 | + stack = traceback.extract_stack() | ||
| 115 | + stacklevel = 1 | ||
| 116 | + for stacklevel, frame in enumerate(reversed(stack), start=1): | ||
| 117 | + frame_dir = os.path.abspath(os.path.dirname(frame.filename)) | ||
| 118 | + if not frame_dir.startswith(pg_dir): | ||
| 119 | + break | ||
| 120 | + warnings.warn( | ||
| 121 | + message=message, category=category, stacklevel=stacklevel, source=source | ||
| 122 | + ) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,7 +2,6 @@ | |||
| 2 | 2 | GitLab API: | |
| 3 | 3 | https://docs.gitlab.com/ee/api/job_artifacts.html | |
| 4 | 4 | """ | |
| 5 | - import warnings | ||
| 6 | 5 | from typing import Any, Callable, Optional, TYPE_CHECKING | |
| 7 | 6 | ||
| 8 | 7 | import requests | |
@@ -34,10 +33,12 @@ def __call__( | |||
| 34 | 33 | *args: Any, | |
| 35 | 34 | **kwargs: Any, | |
| 36 | 35 | ) -> Optional[bytes]: | |
| 37 | - warnings.warn( | ||
| 38 | - "The project.artifacts() method is deprecated and will be " | ||
| 39 | - "removed in a future version. Use project.artifacts.download() instead.\n", | ||
| 40 | - DeprecationWarning, | ||
| 36 | + utils.warn( | ||
| 37 | + message=( | ||
| 38 | + "The project.artifacts() method is deprecated and will be removed in a " | ||
| 39 | + "future version. Use project.artifacts.download() instead.\n" | ||
| 40 | + ), | ||
| 41 | + category=DeprecationWarning, | ||
| 41 | 42 | ) | |
| 42 | 43 | return self.download( | |
| 43 | 44 | *args, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,3 @@ | |||
| 1 | - import warnings | ||
| 2 | 1 | from typing import Any, Callable, cast, Dict, List, Optional, TYPE_CHECKING, Union | |
| 3 | 2 | ||
| 4 | 3 | import requests | |
@@ -548,10 +547,12 @@ def transfer(self, to_namespace: Union[int, str], **kwargs: Any) -> None: | |||
| 548 | 547 | ||
| 549 | 548 | @cli.register_custom_action("Project", ("to_namespace",)) | |
| 550 | 549 | def transfer_project(self, *args: Any, **kwargs: Any) -> None: | |
| 551 | - warnings.warn( | ||
| 552 | - "The project.transfer_project() method is deprecated and will be " | ||
| 553 | - "removed in a future version. Use project.transfer() instead.", | ||
| 554 | - DeprecationWarning, | ||
| 550 | + utils.warn( | ||
| 551 | + message=( | ||
| 552 | + "The project.transfer_project() method is deprecated and will be " | ||
| 553 | + "removed in a future version. Use project.transfer() instead." | ||
| 554 | + ), | ||
| 555 | + category=DeprecationWarning, | ||
| 555 | 556 | ) | |
| 556 | 557 | return self.transfer(*args, **kwargs) | |
| 557 | 558 | ||
@@ -562,10 +563,12 @@ def artifact( | |||
| 562 | 563 | *args: Any, | |
| 563 | 564 | **kwargs: Any, | |
| 564 | 565 | ) -> Optional[bytes]: | |
| 565 | - warnings.warn( | ||
| 566 | - "The project.artifact() method is deprecated and will be " | ||
| 567 | - "removed in a future version. Use project.artifacts.raw() instead.", | ||
| 568 | - DeprecationWarning, | ||
| 566 | + utils.warn( | ||
| 567 | + message=( | ||
| 568 | + "The project.artifact() method is deprecated and will be " | ||
| 569 | + "removed in a future version. Use project.artifacts.raw() instead." | ||
| 570 | + ), | ||
| 571 | + category=DeprecationWarning, | ||
| 569 | 572 | ) | |
| 570 | 573 | return self.artifacts.raw(*args, **kwargs) | |
| 571 | 574 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,6 +16,7 @@ | |||
| 16 | 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 17 | 17 | ||
| 18 | 18 | import json | |
| 19 | + import warnings | ||
| 19 | 20 | ||
| 20 | 21 | from gitlab import utils | |
| 21 | 22 | ||
@@ -76,3 +77,20 @@ def test_json_serializable(self): | |||
| 76 | 77 | ||
| 77 | 78 | obj = utils.EncodedId("we got/a/path") | |
| 78 | 79 | assert '"we%20got%2Fa%2Fpath"' == json.dumps(obj) | |
| 80 | + | ||
| 81 | + | ||
| 82 | + class TestWarningsWrapper: | ||
| 83 | + def test_warn(self): | ||
| 84 | + warn_message = "short and stout" | ||
| 85 | + warn_source = "teapot" | ||
| 86 | + | ||
| 87 | + with warnings.catch_warnings(record=True) as caught_warnings: | ||
| 88 | + utils.warn(message=warn_message, category=UserWarning, source=warn_source) | ||
| 89 | + assert len(caught_warnings) == 1 | ||
| 90 | + warning = caught_warnings[0] | ||
| 91 | + # File name is this file as it is the first file outside of the `gitlab/` path. | ||
| 92 | + assert __file__ == warning.filename | ||
| 93 | + assert warning.category == UserWarning | ||
| 94 | + assert isinstance(warning.message, UserWarning) | ||
| 95 | + assert warn_message == str(warning.message) | ||
| 96 | + assert warn_source == warning.source | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments