@@ -773,6 +773,46 @@ def test_special_chars_csh(self):
773773 self .assertTrue (env_name .encode () in lines [0 ])
774774 self .assertEndsWith (lines [1 ], env_name .encode ())
775775
776+ # gh-140006: the fish prompt override must keep working when a user
777+ # function shadows a builtin it relies on.
778+ @unittest .skipIf (os .name == 'nt' , 'fish is not available on Windows' )
779+ def test_fish_activate_shadowed_builtins (self ):
780+ """
781+ The fish prompt override restores the exit status through `source` and
782+ prints through `printf`/`echo`/`set_color`. A user function that
783+ shadows one of those builtins (a common pattern for `.`-style directory
784+ navigators) must not hijack the prompt or break status restoration.
785+ """
786+ fish = shutil .which ('fish' )
787+ if fish is None :
788+ self .skipTest ('fish required for this test' )
789+ rmtree (self .env_dir )
790+ builder = venv .EnvBuilder (clear = True )
791+ builder .create (self .env_dir )
792+ activate = os .path .join (self .env_dir , self .bindir , 'activate.fish' )
793+ test_script = os .path .join (self .env_dir , 'test_shadowed_builtins.fish' )
794+ with open (test_script , "w" ) as f :
795+ f .write (
796+ # The pre-existing prompt reports the status it receives;
797+ # activation copies it to _old_fish_prompt.
798+ 'function fish_prompt; builtin echo "OLDSTATUS=$status"; end\n '
799+ f'source { shlex .quote (activate )} \n '
800+ # Shadow every builtin the override uses. A dot-navigator that
801+ # lists the directory is the reported failure.
802+ 'function .; builtin echo DOT_LEAK; end\n '
803+ 'function source; builtin echo SOURCE_LEAK; end\n '
804+ 'function echo; command echo ECHO_LEAK; end\n '
805+ 'function printf; command printf PRINTF_LEAK; end\n '
806+ 'function set_color; command true; end\n '
807+ 'function _exit7; return 7; end\n '
808+ '_exit7\n '
809+ 'fish_prompt\n '
810+ )
811+ out , err = check_output ([fish , '--no-config' , test_script ])
812+ text = out .decode ()
813+ self .assertNotIn ('LEAK' , text )
814+ self .assertIn ('OLDSTATUS=7' , text )
815+
776816 # gh-124651: test quoted strings on Windows
777817 @unittest .skipUnless (os .name == 'nt' , 'only relevant on Windows' )
778818 def test_special_chars_windows (self ):
0 commit comments