ruff W605
labelled unknown
Analysis Nemotron 3 Super
Flags backslash-character combinations in string literals that do not form valid Python escape sequences.
Fix: Replace the invalid escape sequence by doubling the backslash before the character to treat it as a literal backslash followed by that character, preserving all other string content and quote style.
12 hazards
- In raw strings (r"..."), doubling backslashes introduces extra literal backslashes, altering the intended pattern (e.g., r"\." becomes r"\\." which matches two backslashes then a dot).
- In byte strings, the fix may produce invalid byte escape sequences if the character after the backslash is not a valid hex digit or octal digit, causing a SyntaxError.
- If the string is part of a larger expression where the backslash was intended as a line continuation (outside string literals), the fix does not apply and is irrelevant, but misidentification could lead to incorrect changes.
- When the invalid escape appears in a docstring or comment-like context inside a string, doubling the backslash changes the literal text, potentially breaking tools that parse the string content (e.g., help(), doctests).
- If the string uses triple quotes and the invalid escape spans across implicit line joining due to a backslash at end-of-line inside the string, fixing it may disrupt the line continuation semantics within the string content.
- In f-strings, if the invalid escape occurs inside an expression part ({...}), the fix is not applied there; but if mistakenly applied, it would corrupt the expression syntax.
- If the string is adjacent to another string literal for concatenation (e.g., "a" "b"), and the fix is applied only to one part, the resulting concatenated string may have unintended backslash duplication.
- When the invalid escape is immediately followed by a quote of the same kind that ends the string (e.g., "\""), doubling the backslash may interfere with the string termination if not handled correctly by the lexer during refactoring.
- If the string contains mixed valid and invalid escapes (e.g., "\n\_"), fixing only the invalid part may create an inconsistent interpretation where the valid escape remains unchanged but the invalid one becomes literal, which may be the intent but must be verified.
- In code generated by macros or templating systems where backslashes are placeholders, doubling them could break the generator's assumptions about the output format.
- When the string is used in a regex context via re.sub or similar, doubling backslashes changes the number of escape layers, potentially requiring compensatory changes elsewhere in the pattern.
- If the invalid escape is part of a Unicode name escape like \N{...} with invalid contents, doubling the backslash yields a literal backslash-N, which is not equivalent and may raise a different error at runtime.
Findings
| program | oracle | label | judge | status | summary |
|---|---|---|---|---|---|
| r1-p001 | fix-changes-behavior | labelled safe | intended-change · low | duplicate | The rule rewrites the invalid escape sequence '\.' into a raw string r'\.' to eliminate the SyntaxWarning, which is exactly the documented purpose. The program… |
| r1-p002 | fix-changes-behavior | labelled safe | intended-change · low | duplicate | The rule rewrites the string literal containing an invalid escape sequence '\_' into a raw string r'\_' to eliminate the SyntaxWarning, which is the documented… |
| r1-p004 | fix-changes-behavior | labelled safe | intended-change · low | duplicate | The rule rewrites the invalid escape sequence '\_' to the valid escaped backslash '\\_', which changes the string value from a newline followed by '_' to a new… |
| r1-p005 | fix-changes-behavior | labelled safe | intended-change · low | duplicate | The rule rewrites the string literal '\_' to a raw string r'\_' to eliminate the SyntaxWarning about an invalid escape sequence. The observed difference is the… |
| r1-p006 | fix-changes-behavior | labelled safe | intended-change · low | duplicate | The rule rewrites an invalid escape sequence '\.' to a raw string r'\.' to eliminate the SyntaxWarning, which is exactly the documented purpose. The stderr dif… |
| r1-p007 | fix-changes-behavior | labelled safe | intended-change · low | duplicate | The rule rewrites an invalid escape sequence '\.' to a raw string r'\.' to eliminate the SyntaxWarning, which is the documented purpose of the fix. The program… |
| r1-p008 | fix-changes-behavior | labelled safe | intended-change · low | duplicate | The rule rewrites the string literal to a raw string to eliminate the SyntaxWarning about the invalid escape sequence '\_'. The stderr difference (warning disa… |
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | fix-changes-behavior | String concatenation adjacency | If the string is adjacent to another string literal for concatenation (e.g., "a" "b"), and the fix is applied only to one part, the resulting concatenated string may have unintended backslash duplicat |
| r1-p002 | fix-changes-behavior | Mutable default arguments and aliasing | mutable default arguments and aliasing after a rewrite |
| r1-p003 | silent | Line continuation misidentification | If the string is part of a larger expression where the backslash was intended as a line continuation (outside string literals), the fix does not apply and is irrelevant, but misidentification could le |
| r1-p004 | fix-changes-behavior | Mixed valid and invalid escapes | If the string contains mixed valid and invalid escapes (e.g., "\n\_"), fixing only the invalid part may create an inconsistent interpretation where the valid escape remains unchanged but the invalid o |
| r1-p005 | fix-changes-behavior | Context managers without close() | context managers that are not files, objects with write() but no close() |
| r1-p006 | fix-changes-behavior | Numeric coercion and arithmetic | int/float/bool coercion, Decimal, division and rounding |
| r1-p007 | fix-changes-behavior | Regex substitution backfire | When the string is used in a regex context via re.sub or similar, doubling backslashes changes the number of escape layers, potentially requiring compensatory changes elsewhere in the pattern. |
| r1-p008 | fix-changes-behavior | File write modes and truncation | file modes and truncation, partial writes, non-str data passed to write |
Sources
r1-p001 · String concatenation adjacency
1s = '\.' 'rest'
2t = s
3print(repr(t))
4if '__' in t:
5 print('double backslash')
6else:
7 print('single backslash')
--- orig.py 2026-10-17 16:50:20.020514587 -0400 +++ fixed.py 2026-10-17 16:50:20.224518552 -0400 @@ -1,4 +1,4 @@ -s = '\.' 'rest' +s = r'\.' 'rest' t = s print(repr(t)) if '__' in t:
'\\.rest' single backslash
r1-p002 · Mutable default arguments and aliasing
1def f(x=['\_']):
2 x[0] = 'changed'
3 return x
4print(f())
5print(f())
6s = ['\_']
7f(s)
8print(s)
--- orig.py 2026-10-17 16:50:20.330520613 -0400 +++ fixed.py 2026-10-17 16:50:20.541524714 -0400 @@ -1,8 +1,8 @@ -def f(x=['\_']): +def f(x=[r'\_']): x[0] = 'changed' return x print(f()) print(f()) -s = ['\_'] +s = [r'\_'] f(s) print(s)
['changed'] ['changed'] ['changed']
r1-p003 · Line continuation misidentification
1total = 1 + \
2 2
3print(total)
4x = 'hello'
5# no trigger here
3
r1-p004 · Mixed valid and invalid escapes
1s = '\n\_'
2print(repr(s))
3print(len(s))
4for c in s:
5 print(ord(c))
--- orig.py 2026-10-17 16:50:20.778529321 -0400 +++ fixed.py 2026-10-17 16:50:20.992533481 -0400 @@ -1,4 +1,4 @@ -s = '\n\_' +s = '\n\\_' print(repr(s)) print(len(s)) for c in s:
'\n\\_' 3 10 92 95
r1-p005 · Context managers without close()
1class Logger:
2 def __init__(self):
3 self.buf = []
4 def write(self, msg):
5 self.buf.append(msg)
6 def __enter__(self):
7 return self
8 def __exit__(self, *args):
9 pass
10with Logger() as log:
11 log.write('\_')
12print(log.buf)
13print('len:', len(log.buf[0]))
--- orig.py 2026-10-17 16:50:21.096535501 -0400 +++ fixed.py 2026-10-17 16:50:21.300539462 -0400 @@ -8,6 +8,6 @@ def __exit__(self, *args): pass with Logger() as log: - log.write('\_') + log.write(r'\_') print(log.buf) print('len:', len(log.buf[0]))
['\\_'] len: 2
r1-p006 · Numeric coercion and arithmetic
1from decimal import Decimal
2s = '\.'
3print(bool(s))
4print(int(s, 16) if all(c in '0123456789abcdefABCDEF' for c in s.replace('\\', '')) else 'NaN')
5d = Decimal('1.5')
6print(d / 2)
7print(round(2.5))
--- orig.py 2026-10-17 16:50:21.403541462 -0400 +++ fixed.py 2026-10-17 16:50:21.613545540 -0400 @@ -1,5 +1,5 @@ from decimal import Decimal -s = '\.' +s = r'\.' print(bool(s)) print(int(s, 16) if all(c in '0123456789abcdefABCDEF' for c in s.replace('\\', '')) else 'NaN') d = Decimal('1.5')
True NaN 0.75 2
r1-p007 · Regex substitution backfire
1import re
2pattern = '\.'
3text = 'a.b'
4result = re.sub(pattern, 'X', text)
5print(result)
6print('expected: aXb')
7if result == 'aXb':
8 print('match')
9else:
10 print('mismatch:', repr(result))
--- orig.py 2026-10-17 16:50:21.723547676 -0400 +++ fixed.py 2026-10-17 16:50:21.933551754 -0400 @@ -1,5 +1,5 @@ import re -pattern = '\.' +pattern = r'\.' text = 'a.b' result = re.sub(pattern, 'X', text) print(result)
aXb expected: aXb match
r1-p008 · File write modes and truncation
1with open('test.txt', 'w') as f:
2 f.write('\_')
3with open('test.txt', 'r') as f:
4 content = f.read()
5print(repr(content))
6import os
7os.remove('test.txt')
--- orig.py 2026-10-17 16:50:22.036553753 -0400 +++ fixed.py 2026-10-17 16:50:22.239557691 -0400 @@ -1,5 +1,5 @@ with open('test.txt', 'w') as f: - f.write('\_') + f.write(r'\_') with open('test.txt', 'r') as f: content = f.read() print(repr(content))
'\\_'