BorisovAI
All posts
Bug Fixtrend-analisisClaude Code

F-Strings and Regex: A Debugging Tale

F-Strings and Regex: A Debugging Tale

Debugging SSE Streams: When Python’s F-Strings Fight Back

The task was straightforward—implement real-time streaming for the trend analysis engine. Our trend-analisis project needed to push scoring updates to the client as they happened, and Server-Sent Events seemed like the perfect fit. Server running, tests queued up, confidence high. Then reality hit.

I’d built the SSE endpoint to stream analysis steps back to the browser, each update containing a progress message and metrics. The backend was spitting out data, the client was supposedly receiving it, but somewhere in that pipeline, something was getting mangled. The streaming wasn’t working properly, and I needed to figure out why before moving forward on the feat/scoring-v2-tavily-citations branch.

First thing I did was fire up a quick analysis and watch the SSE stream directly. The console showed nothing meaningful. Data was flowing, but the format was wrong. My initial thought: encoding issue. Windows terminals love to mangle UTF-8 text, showing garbled characters where readable text should be. But this felt different.

Then I spotted the culprit—hidden in plain sight in an f-string: rf'...'. Those raw f-strings are dangerous when you’re building regex patterns. Inside that f-string lived a regex quantifier: {1,4}. Python saw those braces and thought they were variable interpolation syntax, not regex metacharacters. The curly braces got interpreted as a Python expression, causing the regex to fail silently and the entire pattern matching to break down.

The fix was embarrassingly simple: double the braces. {{1,4}} instead of {1,4}. When you’re building raw f-strings that contain regex, the Python parser still processes the braces, so you need to escape them. It’s one of those gotchas that catches experienced developers because it looks right—raw strings are supposed to preserve everything literally, right? Not quite. The f part still does its job.

While debugging, I also noticed all the analysis step labels needed to be in Russian for consistency with the UI. The main headings—lather, rinse, all of them—got mapped to their Russian equivalents. Only “Stats” remained untranslated, so I added it to the localization map too. After the restart and a fresh verification run, the console confirmed everything was now properly internationalized.

The lesson here is subtle but important: raw f-strings (rf'...') are not truly “raw” in the way that raw strings alone are. They’re still processed for variable interpolation at the braces level. If your regex or string literal contains regex quantifiers or other brace-based syntax, you need to escape those braces with doubling. It’s a trap because the intent seems clear—you wanted raw, you got raw—but Python’s parser is more sophisticated than it appears.

Restart successful. Tests passing. The SSE stream now flows cleanly to the client, each analysis step arriving with proper formatting and localized labels. The trend scorer is ready for the next phase.

😄 How did the programmer die in the shower? He read the shampoo bottle instructions: Lather. Rinse. Repeat.

Metadata

Session ID:
grouped_trend-analisis_20260209_0003
Branch:
feat/scoring-v2-tavily-citations
Dev Joke
Спор yarn vs npm — единственная война, где обе стороны проигрывают, а разработчик страдает.

Rate this content

0/1000