Skip to content

Commit 981e81e

Browse files
authored
Merge pull request #359 from simvue-io/hotfix/fix-lost-docstrings
Fix missing docstrings due to decoration
2 parents 8cb9ad4 + df414bf commit 981e81e

File tree

7 files changed

+36
-33
lines changed

7 files changed

+36
-33
lines changed

poetry.lock

Lines changed: 4 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ pytest-cov = ">=4.1,<6.0"
7070
pytest-mock = "^3.14.0"
7171
pytest-sugar = "^1.0.0"
7272
pytest-xdist = "^3.6.1"
73+
jinja2 = "^3.1.4"
7374

7475
[build-system]
7576
requires = ["poetry-core"]

simvue/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def get_runs(
279279
alerts : bool, optional
280280
whether to include alert information in the response.
281281
Default False.
282-
format : str ('dict' | 'dataframe'), optional
282+
format : Literal['dict', 'dataframe'], optional
283283
the structure of the response, either a dictionary or a dataframe.
284284
Default is 'dict'. Pandas must be installed for 'dataframe'.
285285
count : int, optional
@@ -932,9 +932,9 @@ def get_metric_values(
932932
----------
933933
metric_names : list[str]
934934
the names of metrics to return values for
935-
xaxis : str ('step' | 'time' | 'timestamp')
935+
xaxis : Literal['step', 'time', 'timestamp']
936936
the xaxis type
937-
output_format : str ('dataframe' | 'list')
937+
output_format : Literal['dataframe', 'list']
938938
the format of the output, either a list or a Pandas dataframe
939939
run_ids : list[str], optional
940940
list of runs by id to include within metric retrieval

simvue/run.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import re
2121
import sys
2222
import time
23+
import functools
2324
import platform
2425
import typing
2526
import uuid
@@ -63,6 +64,7 @@
6364
def check_run_initialised(
6465
function: typing.Callable[..., typing.Any],
6566
) -> typing.Callable[..., typing.Any]:
67+
@functools.wraps(function)
6668
def _wrapper(self: "Run", *args: typing.Any, **kwargs: typing.Any) -> typing.Any:
6769
if not self._simvue:
6870
raise RuntimeError(
@@ -71,8 +73,6 @@ def _wrapper(self: "Run", *args: typing.Any, **kwargs: typing.Any) -> typing.Any
7173
)
7274
return function(self, *args, **kwargs)
7375

74-
_wrapper.__name__ = f"{function.__name__}__init_locked"
75-
7676
return _wrapper
7777

7878

@@ -838,8 +838,8 @@ def config(
838838

839839
return True
840840

841-
@check_run_initialised
842841
@skip_if_failed("_aborted", "_suppress_errors", False)
842+
@check_run_initialised
843843
@pydantic.validate_call
844844
def update_metadata(self, metadata: dict[str, typing.Any]) -> bool:
845845
"""
@@ -864,8 +864,8 @@ def update_metadata(self, metadata: dict[str, typing.Any]) -> bool:
864864

865865
return False
866866

867-
@check_run_initialised
868867
@skip_if_failed("_aborted", "_suppress_errors", False)
868+
@check_run_initialised
869869
@pydantic.validate_call
870870
def update_tags(self, tags: list[str]) -> bool:
871871
"""
@@ -885,8 +885,8 @@ def update_tags(self, tags: list[str]) -> bool:
885885

886886
return False
887887

888-
@check_run_initialised
889888
@skip_if_failed("_aborted", "_suppress_errors", False)
889+
@check_run_initialised
890890
@pydantic.validate_call
891891
def log_event(self, message, timestamp: typing.Optional[str] = None) -> bool:
892892
"""
@@ -960,8 +960,8 @@ def _add_metrics_to_dispatch(
960960

961961
return True
962962

963-
@check_run_initialised
964963
@skip_if_failed("_aborted", "_suppress_errors", False)
964+
@check_run_initialised
965965
@pydantic.validate_call
966966
def log_metrics(
967967
self,
@@ -979,8 +979,8 @@ def log_metrics(
979979
self._step += 1
980980
return add_dispatch
981981

982-
@check_run_initialised
983982
@skip_if_failed("_aborted", "_suppress_errors", False)
983+
@check_run_initialised
984984
@pydantic.validate_call
985985
def save_object(
986986
self,
@@ -1035,6 +1035,7 @@ def save_object(
10351035
return self._simvue is not None and self._simvue.save_file(data) is not None
10361036

10371037
@skip_if_failed("_aborted", "_suppress_errors", False)
1038+
@check_run_initialised
10381039
@pydantic.validate_call
10391040
def save_file(
10401041
self,
@@ -1118,8 +1119,8 @@ def save_file(
11181119
# Register file
11191120
return self._simvue.save_file(data) is not None
11201121

1121-
@check_run_initialised
11221122
@skip_if_failed("_aborted", "_suppress_errors", False)
1123+
@check_run_initialised
11231124
@pydantic.validate_call
11241125
def save_directory(
11251126
self,
@@ -1155,8 +1156,8 @@ def save_directory(
11551156

11561157
return True
11571158

1158-
@check_run_initialised
11591159
@skip_if_failed("_aborted", "_suppress_errors", False)
1160+
@check_run_initialised
11601161
@pydantic.validate_call
11611162
def save_all(
11621163
self,
@@ -1186,8 +1187,8 @@ def save_all(
11861187

11871188
return True
11881189

1189-
@check_run_initialised
11901190
@skip_if_failed("_aborted", "_suppress_errors", False)
1191+
@check_run_initialised
11911192
@pydantic.validate_call
11921193
def set_status(
11931194
self, status: typing.Literal["completed", "failed", "terminated"]
@@ -1256,8 +1257,8 @@ def close(self) -> bool:
12561257

12571258
return True
12581259

1259-
@check_run_initialised
12601260
@skip_if_failed("_aborted", "_suppress_errors", False)
1261+
@check_run_initialised
12611262
@pydantic.validate_call
12621263
def set_folder_details(
12631264
self,
@@ -1311,8 +1312,8 @@ def set_folder_details(
13111312

13121313
return False
13131314

1314-
@check_run_initialised
13151315
@skip_if_failed("_aborted", "_suppress_errors", False)
1316+
@check_run_initialised
13161317
@pydantic.validate_call
13171318
def add_alerts(
13181319
self,
@@ -1359,8 +1360,8 @@ def add_alerts(
13591360

13601361
return False
13611362

1362-
@check_run_initialised
13631363
@skip_if_failed("_aborted", "_suppress_errors", None)
1364+
@check_run_initialised
13641365
@pydantic.validate_call
13651366
def create_alert(
13661367
self,
@@ -1521,8 +1522,8 @@ def create_alert(
15211522

15221523
return alert_id
15231524

1524-
@check_run_initialised
15251525
@skip_if_failed("_aborted", "_suppress_errors", False)
1526+
@check_run_initialised
15261527
@pydantic.validate_call
15271528
def log_alert(
15281529
self, identifier: str, state: typing.Literal["ok", "critical"]

simvue/utilities.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import tabulate
77
import pydantic
88
import importlib.util
9+
import functools
910
import contextlib
1011
import os
1112
import typing
@@ -77,6 +78,7 @@ def check_extra(extra_name: str) -> typing.Callable:
7778
def decorator(
7879
class_func: typing.Optional[typing.Callable] = None,
7980
) -> typing.Optional[typing.Callable]:
81+
@functools.wraps(class_func)
8082
def wrapper(self, *args, **kwargs) -> typing.Any:
8183
if extra_name == "plot" and not all(
8284
[
@@ -129,6 +131,7 @@ def skip_if_failed(
129131
"""
130132

131133
def decorator(class_func: typing.Callable) -> typing.Callable:
134+
@functools.wraps(class_func)
132135
def wrapper(self, *args, **kwargs) -> typing.Any:
133136
if getattr(self, failure_attr, None) and getattr(
134137
self, ignore_exc_attr, None
@@ -158,7 +161,7 @@ def wrapper(self, *args, **kwargs) -> typing.Any:
158161
return on_failure_return
159162
raise RuntimeError(err_str)
160163

161-
wrapper.__name__ = f"{class_func.__name__}__fail_safe"
164+
setattr(wrapper, "__fail_safe", True)
162165
return wrapper
163166

164167
return decorator

tests/refactor/test_executor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def test_executor_add_process(
1515
completion_trigger = multiprocessing.Event()
1616
run.init(
1717
f"test_executor_{'success' if successful else 'fail'}",
18-
tags=["simvue_client_unit_tests", request.node.name],
18+
tags=["simvue_client_unit_tests", request.node.name.replace("[", "_").replace("]", "_")],
1919
folder="/simvue_unit_testing"
2020
)
2121

tests/refactor/test_run_class.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def test_log_metrics(
5050
with pytest.raises(RuntimeError):
5151
run.init(
5252
name=f"test_run_{str(uuid.uuid4()).split('-', 1)[0]}",
53-
tags=["simvue_client_unit_tests", request.node.name],
53+
tags=["simvue_client_unit_tests", request.node.name.replace("[", "_").replace("]", "_")],
5454
folder="/simvue_unit_testing",
5555
retention_period="1 hour",
5656
visibility=visibility,
@@ -60,7 +60,7 @@ def test_log_metrics(
6060

6161
run.init(
6262
name=f"test_run_{str(uuid.uuid4()).split('-', 1)[0]}",
63-
tags=["simvue_client_unit_tests", request.node.name],
63+
tags=["simvue_client_unit_tests", request.node.name.replace("[", "_").replace("]", "_")],
6464
folder="/simvue_unit_testing",
6565
visibility=visibility,
6666
resources_metrics_interval=1,
@@ -155,7 +155,7 @@ def thread_func(index: int) -> tuple[int, list[dict[str, typing.Any]], str]:
155155
run.config(suppress_errors=False)
156156
run.init(
157157
name=f"test_runs_multiple_{index + 1}",
158-
tags=["simvue_client_unit_tests", request.node.name],
158+
tags=["simvue_client_unit_tests", request.node.name.replace("[", "_").replace("]", "_")],
159159
folder="/simvue_unit_testing",
160160
retention_period="1 hour",
161161
)
@@ -192,7 +192,7 @@ def thread_func(index: int) -> tuple[int, list[dict[str, typing.Any]], str]:
192192
run_1.config(suppress_errors=False)
193193
run_1.init(
194194
name="test_runs_multiple_unthreaded_1",
195-
tags=["simvue_client_unit_tests", request.node.name],
195+
tags=["simvue_client_unit_tests", request.node.name.replace("[", "_").replace("]", "_")],
196196
folder="/simvue_unit_testing",
197197
retention_period="1 hour",
198198
)
@@ -246,7 +246,7 @@ def test_runs_multiple_series(request: pytest.FixtureRequest) -> None:
246246
run.config(suppress_errors=False)
247247
run.init(
248248
name=f"test_runs_multiple_series_{index}",
249-
tags=["simvue_client_unit_tests", request.node.name],
249+
tags=["simvue_client_unit_tests", request.node.name.replace("[", "_").replace("]", "_")],
250250
folder="/simvue_unit_testing",
251251
retention_period="1 hour",
252252
)
@@ -288,15 +288,15 @@ def test_suppressed_errors(
288288
decorated_funcs = [
289289
name
290290
for name, method in inspect.getmembers(run, inspect.ismethod)
291-
if method.__name__.endswith("__fail_safe")
291+
if hasattr(method, "__fail_safe")
292292
]
293293

294294
if post_init:
295295
decorated_funcs.remove("init")
296296
run.init(
297297
name="test_suppressed_errors",
298298
folder="/simvue_unit_testing",
299-
tags=["simvue_client_unit_tests", request.node.name],
299+
tags=["simvue_client_unit_tests", request.node.name.replace("[", "_").replace("]", "_")],
300300
retention_period="1 hour"
301301
)
302302

@@ -323,7 +323,7 @@ def test_set_folder_details(request: pytest.FixtureRequest) -> None:
323323
with sv_run.Run() as run:
324324
folder_name: str ="/simvue_unit_tests"
325325
description: str = "test description"
326-
tags: list[str] = ["simvue_client_unit_tests", request.node.name]
326+
tags: list[str] = ["simvue_client_unit_tests", request.node.name.replace("[", "_").replace("]", "_")]
327327
run.init(folder=folder_name)
328328
run.set_folder_details(path=folder_name, tags=tags, description=description)
329329

0 commit comments

Comments
 (0)