@@ -225,7 +225,38 @@ def f(_):
225225 click .echo ("interrupted" )
226226
227227 out , err = capsys .readouterr ()
228- assert out == "Password:\n interrupted\n "
228+ # On non-Windows, prompt is passed directly to getpass, not echoed separately
229+ assert out == "\n interrupted\n "
230+
231+
232+ @pytest .mark .skipif (WIN , reason = "Different behavior on windows." )
233+ @pytest .mark .parametrize (
234+ ("call" , "expected_prompt" ),
235+ [
236+ (lambda : click .prompt ("Name" ), "Name: " ),
237+ (lambda : click .prompt ("Pw" , hide_input = True ), "Pw: " ),
238+ (lambda : click .prompt ("IP" , prompt_suffix = "." ), "IP." ),
239+ (lambda : click .confirm ("OK" ), "OK [y/N]: " ),
240+ ],
241+ ids = ["prompt" , "prompt-hidden" , "prompt-custom-suffix" , "confirm" ],
242+ )
243+ def test_full_prompt_passed_to_readline (monkeypatch , call , expected_prompt ):
244+ """On non-Windows, prompt and confirm pass the full prompt text to the
245+ underlying prompt function so readline handles editing correctly.
246+
247+ https://github.com/pallets/click/issues/2968
248+ https://github.com/pallets/click/pull/2969
249+ """
250+ received = []
251+
252+ def capture (text ):
253+ received .append (text )
254+ return "y"
255+
256+ monkeypatch .setattr ("click.termui.visible_prompt_func" , capture )
257+ monkeypatch .setattr ("click.termui.hidden_prompt_func" , capture )
258+ call ()
259+ assert received == [expected_prompt ]
229260
230261
231262def test_prompts_eof (runner ):
@@ -484,17 +515,21 @@ def emulate_input(text):
484515 assert out == "Prompt to stdin with no suffix"
485516 assert err == ""
486517
518+ # On non-Windows the full prompt goes through redirect_stdout so
519+ # nothing leaks to stdout when err=True.
520+ # https://github.com/pallets/click/issues/2968
487521 emulate_input ("asdlkj\n " )
488522 click .prompt ("Prompt to stderr" , err = True )
489523 out , err = capfd .readouterr ()
490- assert out == " "
491- assert err == "Prompt to stderr:"
524+ assert out == ""
525+ assert err == "Prompt to stderr: "
492526
527+ # https://github.com/pallets/click/issues/3019
493528 emulate_input ("asdlkj\n " )
494529 click .prompt ("Prompt to stderr with no suffix" , prompt_suffix = "" , err = True )
495530 out , err = capfd .readouterr ()
496- assert out == "x "
497- assert err == "Prompt to stderr with no suffi "
531+ assert out == ""
532+ assert err == "Prompt to stderr with no suffix "
498533
499534 emulate_input ("y\n " )
500535 click .confirm ("Prompt to stdin" )
@@ -508,17 +543,19 @@ def emulate_input(text):
508543 assert out == "Prompt to stdin with no suffix [y/N]"
509544 assert err == ""
510545
546+ # https://github.com/pallets/click/issues/2968
511547 emulate_input ("y\n " )
512548 click .confirm ("Prompt to stderr" , err = True )
513549 out , err = capfd .readouterr ()
514- assert out == " "
515- assert err == "Prompt to stderr [y/N]:"
550+ assert out == ""
551+ assert err == "Prompt to stderr [y/N]: "
516552
553+ # https://github.com/pallets/click/issues/3019
517554 emulate_input ("y\n " )
518555 click .confirm ("Prompt to stderr with no suffix" , prompt_suffix = "" , err = True )
519556 out , err = capfd .readouterr ()
520- assert out == "] "
521- assert err == "Prompt to stderr with no suffix [y/N"
557+ assert out == ""
558+ assert err == "Prompt to stderr with no suffix [y/N] "
522559
523560 monkeypatch .setattr (click .termui , "isatty" , lambda x : True )
524561 monkeypatch .setattr (click .termui , "getchar" , lambda : " " )
0 commit comments