Summary
set_key (and the dotenv set CLI) writes single-quoted values but only escapes single quotes, not backslashes. Since the single-quoted-value parser treats backslash as an escape character, any value containing a backslash is corrupted when read back.
Reproduction
import dotenv
dotenv.set_key(".env", "PATH", r"C:\Users")
print(dotenv.get_key(".env", "PATH")) # -> "C:Users" (backslash lost)
dotenv.set_key(".env", "RE", r"\d+")
print(dotenv.get_key(".env", "RE")) # -> "d+"
The file ends up containing PATH='C:\Users'. On read, the single-quote parser decodes \U as an escape, so the backslash disappears. Doubling the backslash (C:\\Users) collapses to a single one. This affects Windows paths and regular expressions in particular.
Root cause
In src/dotenv/main.py, set_key builds the quoted output with:
value_out = "'{}'".format(value_to_set.replace("'", "\\'"))
The backslash itself is never escaped, but parser.py decodes \\ -> \ and \' -> ' inside single-quoted values, so the written value does not round-trip.
Fix
Escape backslashes before escaping single quotes so the value round-trips through the parser. A PR follows.
Summary
set_key(and thedotenv setCLI) writes single-quoted values but only escapes single quotes, not backslashes. Since the single-quoted-value parser treats backslash as an escape character, any value containing a backslash is corrupted when read back.Reproduction
The file ends up containing
PATH='C:\Users'. On read, the single-quote parser decodes\Uas an escape, so the backslash disappears. Doubling the backslash (C:\\Users) collapses to a single one. This affects Windows paths and regular expressions in particular.Root cause
In
src/dotenv/main.py,set_keybuilds the quoted output with:The backslash itself is never escaped, but
parser.pydecodes\\->\and\'->'inside single-quoted values, so the written value does not round-trip.Fix
Escape backslashes before escaping single quotes so the value round-trips through the parser. A PR follows.