@@ -40,10 +40,17 @@ def mask_str_in_code(code: str, mask_char: str = 'X') -> str:
40
40
"""
41
41
# First handle f-strings separately using regex
42
42
# This regex matches f-strings with their content
43
- fstring_pattern = r'(f)(""".*?"""|\'\'\'.*?\'\'\'|".*?"|\'.*?\')'
43
+ # Make sure 'f' is preceded by something that indicates start of a new token
44
+ fstring_pattern = r'(?:^|[^a-zA-Z0-9_"\'])(f)(""".*?"""|\'\'\'.*?\'\'\'|".*?"|\'.*?\')'
44
45
45
46
def mask_fstring (match ):
46
- prefix = match .group (1 )
47
+ # Get the character before 'f' (if any)
48
+ full_match = match .group (0 )
49
+ prefix_char = ''
50
+ if not full_match .startswith ('f' ):
51
+ prefix_char = full_match [0 ]
52
+
53
+ prefix = match .group (1 ) # 'f'
47
54
full_string = match .group (2 )
48
55
quote = ''
49
56
content = ''
@@ -57,7 +64,7 @@ def mask_fstring(match):
57
64
58
65
# Mask everything in f-string content
59
66
masked_content = mask_char * len (content )
60
- return prefix + quote + masked_content + quote
67
+ return prefix_char + prefix + quote + masked_content + quote
61
68
62
69
# Apply f-string masking
63
70
code = re .sub (fstring_pattern , mask_fstring , code , flags = re .DOTALL )
@@ -76,7 +83,6 @@ def mask_fstring(match):
76
83
if token .type == tokenize .STRING :
77
84
# Get the string content including quotes
78
85
string_value = token .string
79
-
80
86
# Skip if it looks like an f-string (already handled)
81
87
if string_value .startswith (('f"' , "f'" , 'f"""' , "f'''" )):
82
88
# Add any code between last token and this one
@@ -182,4 +188,4 @@ def mask_fstring(match):
182
188
masked_parts .append ('\n ' )
183
189
masked_parts .extend ('\n ' .join (lines [end_line :]))
184
190
185
- return '' .join (masked_parts )
191
+ return '' .join (masked_parts )
0 commit comments