12 fix docs #13

Merged
Berack96 merged 18 commits from 12-fix-docs into main 2025-10-02 01:41:00 +02:00
2 changed files with 41 additions and 9 deletions
Showing only changes of commit ca463f9f5f - Show all commits

View File

@@ -1,3 +1,4 @@
import inspect
import time
import traceback
from typing import TypeVar, Callable, Generic, Iterable, Type
@@ -45,17 +46,24 @@ class WrapperHandler(Generic[W]):
Raises:
Exception: If all wrappers fail after retries.
"""
log_info(f"{inspect.getsource(func).strip()} {inspect.getclosurevars(func).nonlocals}")
iterations = 0
while iterations < len(self.wrappers):
wrapper = self.wrappers[self.index]
wrapper_name = wrapper.__class__.__name__
copilot-pull-request-reviewer[bot] commented 2025-10-02 01:29:51 +02:00 (Migrated from github.com)
Review

Using inspect.getsource() in production code can be expensive and may fail in some environments (compiled code, frozen executables). Consider logging only essential information like function name.

        log_info(f"Calling function '{func.__name__}' from module '{func.__module__}'")
Using `inspect.getsource()` in production code can be expensive and may fail in some environments (compiled code, frozen executables). Consider logging only essential information like function name. ```suggestion log_info(f"Calling function '{func.__name__}' from module '{func.__module__}'") ```
copilot-pull-request-reviewer[bot] commented 2025-10-02 01:37:57 +02:00 (Migrated from github.com)
Review

Using inspect.getsource() for logging may have performance implications as it reads and parses source code on every function call. Consider adding a debug flag to conditionally enable this detailed logging.

Using inspect.getsource() for logging may have performance implications as it reads and parses source code on every function call. Consider adding a debug flag to conditionally enable this detailed logging.
try:
wrapper = self.wrappers[self.index]
log_info(f"Trying wrapper: {wrapper} - function {func}")
log_info(f"try_call {wrapper_name}")
result = func(wrapper)
log_info(f"{wrapper_name} succeeded")
self.retry_count = 0
return result
except Exception as e:
self.retry_count += 1
log_warning(f"{wrapper} failed {self.retry_count}/{self.retry_per_wrapper}: {WrapperHandler.__concise_error(e)}")
error = WrapperHandler.__concise_error(e)
log_warning(f"{wrapper_name} failed {self.retry_count}/{self.retry_per_wrapper}: {error}")
if self.retry_count >= self.retry_per_wrapper:
self.index = (self.index + 1) % len(self.wrappers)
@@ -64,7 +72,7 @@ class WrapperHandler(Generic[W]):
else:
time.sleep(self.retry_delay)
raise Exception(f"All wrappers failed after retries")
raise Exception(f"All wrappers failed, latest error: {error}")
def try_call_all(self, func: Callable[[W], T]) -> dict[str, T]:
"""
@@ -78,16 +86,20 @@ class WrapperHandler(Generic[W]):
Raises:
Exception: If all wrappers fail.
"""
log_info(f"{inspect.getsource(func).strip()} {inspect.getclosurevars(func).nonlocals}")
results = {}
log_info(f"All wrappers: {[wrapper.__class__ for wrapper in self.wrappers]} - function {func}")
for wrapper in self.wrappers:
wrapper_name = wrapper.__class__.__name__
try:
result = func(wrapper)
log_info(f"{wrapper_name} succeeded")
results[wrapper.__class__] = result
except Exception as e:
log_warning(f"{wrapper} failed: {WrapperHandler.__concise_error(e)}")
error = WrapperHandler.__concise_error(e)
log_warning(f"{wrapper_name} failed: {error}")
if not results:
raise Exception("All wrappers failed")
raise Exception(f"All wrappers failed, latest error: {error}")
return results
@staticmethod

View File

@@ -54,7 +54,7 @@ class TestWrapperHandler:
with pytest.raises(Exception) as exc_info:
handler.try_call(lambda w: w.do_something())
assert "All wrappers failed after retries" in str(exc_info.value)
assert "All wrappers failed" in str(exc_info.value)
def test_success_on_first_try(self):
wrappers = [MockWrapper, FailingWrapper]
@@ -121,7 +121,6 @@ class TestWrapperHandler:
handler_all_fail.try_call_all(lambda w: w.do_something())
assert "All wrappers failed" in str(exc_info.value)
def test_wrappers_with_parameters(self):
wrappers = [FailingWrapperWithParameters, MockWrapperWithParameters]
handler: WrapperHandler[MockWrapperWithParameters] = WrapperHandler.build_wrappers(wrappers, try_per_wrapper=2, retry_delay=0)
@@ -130,3 +129,24 @@ class TestWrapperHandler:
assert result == "Success test and 42"
assert handler.index == 1 # Should have switched to the second wrapper
assert handler.retry_count == 0
def test_wrappers_with_parameters_all_fail(self):
wrappers = [FailingWrapperWithParameters, FailingWrapperWithParameters]
handler: WrapperHandler[MockWrapperWithParameters] = WrapperHandler.build_wrappers(wrappers, try_per_wrapper=1, retry_delay=0)
with pytest.raises(Exception) as exc_info:
handler.try_call(lambda w: w.do_something("test", 42))
assert "All wrappers failed" in str(exc_info.value)
def test_try_call_all_with_parameters(self):
wrappers = [FailingWrapperWithParameters, MockWrapperWithParameters]
handler: WrapperHandler[MockWrapperWithParameters] = WrapperHandler.build_wrappers(wrappers, try_per_wrapper=1, retry_delay=0)
results = handler.try_call_all(lambda w: w.do_something("param", 99))
assert results == {MockWrapperWithParameters: "Success param and 99"}
def test_try_call_all_with_parameters_all_fail(self):
wrappers = [FailingWrapperWithParameters, FailingWrapperWithParameters]
handler: WrapperHandler[MockWrapperWithParameters] = WrapperHandler.build_wrappers(wrappers, try_per_wrapper=1, retry_delay=0)
with pytest.raises(Exception) as exc_info:
handler.try_call_all(lambda w: w.do_something("param", 99))
assert "All wrappers failed" in str(exc_info.value)