Skip to content

Commit d3a1e72

Browse files
authored
gh-160782: fix fish quote-escaping gap (GH-160943)
1 parent a683f70 commit d3a1e72

3 files changed

Lines changed: 21 additions & 0 deletions

File tree

‎Lib/test/test_venv.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,18 @@ def test_fish_activate_shadowed_builtins(self):
846846
self.assertNotIn('LEAK', text)
847847
self.assertIn('OLDSTATUS=7', text)
848848

849+
def test_fish_quoting(self):
850+
"""
851+
Test that the template strings are quoted properly (fish)
852+
"""
853+
builder = venv.EnvBuilder()
854+
context = builder.ensure_directories(self.env_dir)
855+
context.script_path = 'activate.fish'
856+
context.prompt = r"x\'$(echo PWNED)'\'"
857+
self.assertEqual(
858+
builder.replace_variables('__VENV_PROMPT__', context),
859+
r"'x\\\'$(echo PWNED)\'\\\''")
860+
849861
# gh-124651: test quoted strings on Windows
850862
@unittest.skipUnless(os.name == 'nt', 'only relevant on Windows')
851863
def test_special_chars_windows(self):

‎Lib/venv/__init__.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,13 +521,20 @@ def quote_ps1(s):
521521
def quote_bat(s):
522522
return s
523523

524+
def quote_fish(s):
525+
# gh-160782: fish reads \\ and \' as escapes inside single quotes
526+
s = s.replace('\\', '\\\\').replace("'", "\\'")
527+
return f"'{s}'"
528+
524529
# gh-124651: need to quote the template strings properly
525530
quote = shlex.quote
526531
script_path = context.script_path
527532
if script_path.endswith('.ps1'):
528533
quote = quote_ps1
529534
elif script_path.endswith('.bat'):
530535
quote = quote_bat
536+
elif script_path.endswith('.fish'):
537+
quote = quote_fish
531538
else:
532539
# fallbacks to POSIX shell compliant quote
533540
quote = shlex.quote
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`venv`: a backslash before a quote in the prompt or the path no longer
2+
breaks ``activate.fish``.

0 commit comments

Comments
 (0)