fix: Use raw string values instead of repr() for str types in display_string#383
fix: Use raw string values instead of repr() for str types in display_string#383kgilpin wants to merge 4 commits intofeat/display-labeled-paramsfrom
Conversation
…_string When APPMAP_DISPLAY_PARAMS=true, repr() wraps string values in quotes (e.g. 'my-api-key'), which breaks the scanner's secret-in-log substring matching. By using the raw string value directly for str types, the recorded value matches what appears in log messages, enabling proper secret leak detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adjusts AppMap parameter/return-value rendering so str values are recorded as their raw string content (not repr()-quoted), improving consistency with log output and enabling reliable secret-in-log substring matching.
Changes:
- Update
display_stringto return rawstrvalues instead ofrepr(val)for strings. - Update unit tests to assert raw string values for parameters/return values.
- Update JSON “expected” AppMap fixtures to match the new string formatting.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
_appmap/event.py |
Changes display_string to emit raw str values instead of repr() output. |
_appmap/test/web_framework.py |
Updates web framework capture assertions to expect raw string values. |
_appmap/test/test_params.py |
Updates parameter-capture assertions/parameterized expectations for str values. |
_appmap/test/test_http.py |
Updates HTTP client capture assertions for raw string query param values. |
_appmap/test/test_events.py |
Updates labeled params/return value assertions and comment to reflect raw strings. |
_appmap/test/data/unittest/expected/unittest.appmap.json |
Updates expected recorded parameter/return str values (and formatting) to raw strings. |
_appmap/test/data/unittest/expected/unittest-no-test-cases.appmap.json |
Updates expected recorded str values to raw strings. |
_appmap/test/data/unittest/expected/pytest.appmap.json |
Updates expected recorded str values to raw strings. |
_appmap/test/data/pytest/expected/pytest-numpy2.appmap.json |
Updates expected recorded str return values to raw strings. |
_appmap/test/data/pytest/expected/pytest-numpy2-no-test-cases.appmap.json |
Updates expected recorded str return values to raw strings. |
_appmap/test/data/pytest/expected/pytest-numpy1.appmap.json |
Updates expected recorded str return values to raw strings. |
_appmap/test/data/pytest/expected/pytest-numpy1-no-test-cases.appmap.json |
Updates expected recorded str return values to raw strings. |
_appmap/test/data/expected.appmap.json |
Updates expected recorded str parameter/return values (including newline escaping) to raw strings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
_appmap/event.py
Outdated
| if _should_display(has_labels): | ||
| try: | ||
| value = repr(val) | ||
| value = val if isinstance(val, str) else repr(val) |
There was a problem hiding this comment.
Using isinstance(val, str) here can trigger class lookups on proxy/lazy objects (the file already avoids isinstance for this reason in _is_list_or_dict), potentially causing side effects or premature evaluation when params display is enabled. Consider avoiding isinstance and instead check the real type (e.g., type(val) is str or issubclass(type(val), str)) before returning the raw value.
| value = val if isinstance(val, str) else repr(val) | |
| val_type = type(val) | |
| value = val if (val_type is str or issubclass(val_type, str)) else repr(val) |
There was a problem hiding this comment.
What about:
issubclass(type(val), str)
There was a problem hiding this comment.
Changed to issubclass(type(val), str) in commit 622ec72.
_appmap/event.py
Outdated
| if _should_display(has_labels): | ||
| try: | ||
| value = repr(val) | ||
| value = val if isinstance(val, str) else repr(val) |
There was a problem hiding this comment.
The comment above still states that parameter display uses repr() to compute a string value, but the implementation now returns the raw value for str types. Please update the comment to reflect the new behavior so it doesn't mislead future readers.
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Updated the comment in commit 622ec72 to clarify that str types are returned as-is and other types use repr().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Agent-Logs-Url: https://github.com/getappmap/appmap-python/sessions/164d7ad2-ff95-401b-a976-40cbc36ab6a5 Co-authored-by: kgilpin <86395+kgilpin@users.noreply.github.com>
| appmap-python pytest | ||
|
|
||
| # Also works for quick local iteration on non-subprocess tests | ||
| APPMAP=true .venv/bin/python -m pytest _appmap/test/test_events.py |
There was a problem hiding this comment.
Note many tests require APPMAP_DISPLAY_PARAMS=true (which tox sets across the board).
Also note uv run is an alternative to using venv directly.
There was a problem hiding this comment.
Looks good to me. We went back and forth on whether strings should be represented in maps verbatim or as a representation; the scanner usage does finally provide a good argument on one over the other.
The test is also a good addition.
Before merging, please:
- fixup the
issubclassand comment fix into the main feature commit, - amend the main feature commit message to include
BREAKING CHANGE:note; this changes the format of the stringified parameters.
One thing I wonder: since we're special casing strings, does it make sense to always capture them, regardless of appmap_display_params value? If it's a string, there is should be no risk of extra serialization overhead. Two potential pitfalls: 1) making sure the class is also always captured in this case, 2) do we want to truncate to avoid putting huge strings in the appmap?
isinstance(val, str)withissubclass(type(val), str)to avoid__class__lookups on proxy/lazy objectsdisplay_stringdocstring/comment to reflect thatstrtypes return raw values (notrepr())