Earlier quoted context omitted.
> In multi-line mode it matches, in single-line mode it does not because there is a newline between cat and the end of the line. A newline is only a terminating newline if it is the last character, the newline after cat is not a terminating newline. You need cat\n$ or cat\n\n to match. This only makes sense if re.search accepted a line to search. It doesn't. It accepts an arbitrary string. I don't think this conversa…
This only makes sense if re.search accepted a line to search. It doesn't. It accepts an arbitrary string. Which is fine because lines are a subset of strings. And whether you want your input treated as a line or a string is decided by your pattern, use ^ and $ and it will be treated as a line, use \A and \Z and it will be treated as a string. The first `\n` in `cat\n\n` is a terminating newline. There just happens to…
Where is this semantic explained in the `re` module docs?
This is totally and completely made up as far as I can tell.
This also seems entirely consistent with my rebuttal:
Me: What you're saying makes sense if condition foo holds.
You: Condition foo holds.
This is uninteresting to me because I see no reason to believe that condition foo holds. Where condition foo is "the input to re.search is expected to be a single line." Or more precisely, apparently, "the input to re.search is expected to be a single line when either ^ or $ appear in the pattern." That is totally bonkers.
> but it explains why things behave the way they do
Firstly, I am not debating with you about the historical reasoning for this. Secondly, I am providing a commentary on the semantics themselves (they suck) and also on your explanation of them in today's context (it doesn't make sense). Thirdly, I am not making a prescriptive argument that established regex engines should change their behavior in any way.
If you're looking to explain why this semantic is the way it is, then I'd expect writing from the original implementors of it. Probably in Perl. I wouldn't at all be surprised if this was an "oops" or if it was implemented in a strictly-line-oriented context, and then someone else decided to keep it unthinkingly when they moved to a non-line-oriented context. From there, compatibility takes over as a reason for why it's with us today.