Prevent Markdown reporter crash when max_length is None#858
Prevent Markdown reporter crash when max_length is None#858PeterDaveHello wants to merge 1 commit intothp:masterfrom
Conversation
lib/urlwatch/tests/test_reporters.py
Outdated
| job_state = _DummyJobState(diff="line1\nline2\nline3") | ||
| reporter = MarkdownReporter(report, report.config["report"]["markdown"], [job_state], datetime.timedelta()) | ||
|
|
||
| output = list(reporter.submit(max_length=10)) |
There was a problem hiding this comment.
Wouldn't max_length in the function become negative?
There was a problem hiding this comment.
It only goes negative if a very small max_length is passed. This is because submit() first does max_length -= len(trimmed_msg) and the trimmed_msg string is about 58 chars, so max_length=10 becomes -48. Even then it just trims and does not crash. If you want to avoid that impression, I can change the test to use a value >= 60.
thp
left a comment
There was a problem hiding this comment.
In which situation would max_length actually become None?
|
Agreed that a plain CLI run won't hit this. The crash only happens when the Markdown reporter output is actually consumed (Python/hook/extension usage): with default |
thp
left a comment
There was a problem hiding this comment.
The more I think about it, the more I think that max_length -= len(trimmed_msg) should be done later (only when trimmed is truthy). If it isn't trimmed, we still want to have the full max_length, and if it is trimmed, something like [...] or [trimmed] might be better to allow for more "payload" and less "boilerplate". In particular, if max_length < len(trimmed_msg), then technically we wouldn't be able to show anything, not even the summary or the details. And if the "trimmed message" is quite small (e.g. "[...]" - 5 characters).
Then again, it's probably the _render() method that should do all deciding and value adding (possibly with an additional return value before the footer), so that it knows what the "real" max length is, and either fit the message in there, or trim it.
In other words:
The message "Hello world" (11 characters) and trimmed_msg = "[...]" (5 characters)
with max_length == 11 should still be:
"Hello world"
but with max_length == 10, should be:
"Hello[...]"
Right now, with max_length == 11, it would be:
"Hello [...]"
Reserve trim notice space only when output is trimmed, keeping exact-length output intact and avoiding None subtraction. Use a short marker when the notice exceeds max_length. Expand tests for trimming notice, fallback marker, tiny/zero limits, total length checks, and exact-length output.
4f5f740 to
ce8e240
Compare
| trimmed_marker = "[...]\n" | ||
| if len(trimmed_marker) > max_length: | ||
| trimmed_marker = "" | ||
| reserved_length = max_length - len(trimmed_marker) if trimmed_marker else max_length |
There was a problem hiding this comment.
If trimmed_marker is the empty string (the only way if trimmed_marker should evaluate to falsy), then len(trimmed_marker) == 0, so the result is the same.
| reserved_length = max_length - len(trimmed_marker) if trimmed_marker else max_length | |
| reserved_length = max_length - len(trimmed_marker) |
| if len(trimmed_marker) > max_length: | ||
| trimmed_marker = "" | ||
| reserved_length = max_length - len(trimmed_marker) if trimmed_marker else max_length | ||
| trimmed, summary, details, footer = MarkdownReporter._render( |
There was a problem hiding this comment.
It's unfortunate that we have to call MarkdownReporter._render() twice here. Can't MarkdownReporter._render() contain all that trimming logic?
thp
left a comment
There was a problem hiding this comment.
See comments. Ideally call MarkdownReporter._render() only once and let it figure out trimming (since MarkdownReporter._render() already returns the trimmed status, might as well return trimmed_msg instead (being the empty string if not trimmed or not enough space).
Guard the None max_length case so markdown reporter no longer raises TypeError on enablement. Add reporter tests for unlimited and trimmed paths to prevent regression.
GitHub Copilot summary: