@@ -187,16 +187,21 @@ def find_py(cls):
187187 )
188188 return py_exe
189189
190+ def get_py_exe (self ):
191+ if not self .py_exe :
192+ self .py_exe = self .find_py ()
193+ return self .py_exe
194+
190195 def run_py (self , args , env = None , allow_fail = False , expect_returncode = 0 , argv = None ):
191196 if not self .py_exe :
192197 self .py_exe = self .find_py ()
193198
194199 ignore = {"VIRTUAL_ENV" , "PY_PYTHON" , "PY_PYTHON2" , "PY_PYTHON3" }
195200 env = {
196201 ** {k .upper (): v for k , v in os .environ .items () if k .upper () not in ignore },
197- ** {k .upper (): v for k , v in (env or {}).items ()},
198202 "PYLAUNCHER_DEBUG" : "1" ,
199203 "PYLAUNCHER_DRYRUN" : "1" ,
204+ ** {k .upper (): v for k , v in (env or {}).items ()},
200205 }
201206 if not argv :
202207 argv = [self .py_exe , * args ]
@@ -496,61 +501,93 @@ def test_virtualenv_with_env(self):
496501
497502 def test_py_shebang (self ):
498503 with self .py_ini (TEST_PY_COMMANDS ):
499- with self .script ("#! /usr/bin/env python -prearg" ) as script :
504+ with self .script ("#! /usr/bin/python -prearg" ) as script :
500505 data = self .run_py ([script , "-postarg" ])
501506 self .assertEqual ("PythonTestSuite" , data ["SearchInfo.company" ])
502507 self .assertEqual ("3.100" , data ["SearchInfo.tag" ])
503508 self .assertEqual (f"X.Y.exe -prearg { script } -postarg" , data ["stdout" ].strip ())
504509
505510 def test_py2_shebang (self ):
506511 with self .py_ini (TEST_PY_COMMANDS ):
507- with self .script ("#! /usr/bin/env python2 -prearg" ) as script :
512+ with self .script ("#! /usr/bin/python2 -prearg" ) as script :
508513 data = self .run_py ([script , "-postarg" ])
509514 self .assertEqual ("PythonTestSuite" , data ["SearchInfo.company" ])
510515 self .assertEqual ("3.100-32" , data ["SearchInfo.tag" ])
511516 self .assertEqual (f"X.Y-32.exe -prearg { script } -postarg" , data ["stdout" ].strip ())
512517
513518 def test_py3_shebang (self ):
514519 with self .py_ini (TEST_PY_COMMANDS ):
515- with self .script ("#! /usr/bin/env python3 -prearg" ) as script :
520+ with self .script ("#! /usr/bin/python3 -prearg" ) as script :
516521 data = self .run_py ([script , "-postarg" ])
517522 self .assertEqual ("PythonTestSuite" , data ["SearchInfo.company" ])
518523 self .assertEqual ("3.100-arm64" , data ["SearchInfo.tag" ])
519524 self .assertEqual (f"X.Y-arm64.exe -X fake_arg_for_test -prearg { script } -postarg" , data ["stdout" ].strip ())
520525
521526 def test_py_shebang_nl (self ):
522527 with self .py_ini (TEST_PY_COMMANDS ):
523- with self .script ("#! /usr/bin/env python -prearg\n " ) as script :
528+ with self .script ("#! /usr/bin/python -prearg\n " ) as script :
524529 data = self .run_py ([script , "-postarg" ])
525530 self .assertEqual ("PythonTestSuite" , data ["SearchInfo.company" ])
526531 self .assertEqual ("3.100" , data ["SearchInfo.tag" ])
527532 self .assertEqual (f"X.Y.exe -prearg { script } -postarg" , data ["stdout" ].strip ())
528533
529534 def test_py2_shebang_nl (self ):
530535 with self .py_ini (TEST_PY_COMMANDS ):
531- with self .script ("#! /usr/bin/env python2 -prearg\n " ) as script :
536+ with self .script ("#! /usr/bin/python2 -prearg\n " ) as script :
532537 data = self .run_py ([script , "-postarg" ])
533538 self .assertEqual ("PythonTestSuite" , data ["SearchInfo.company" ])
534539 self .assertEqual ("3.100-32" , data ["SearchInfo.tag" ])
535540 self .assertEqual (f"X.Y-32.exe -prearg { script } -postarg" , data ["stdout" ].strip ())
536541
537542 def test_py3_shebang_nl (self ):
538543 with self .py_ini (TEST_PY_COMMANDS ):
539- with self .script ("#! /usr/bin/env python3 -prearg\n " ) as script :
544+ with self .script ("#! /usr/bin/python3 -prearg\n " ) as script :
540545 data = self .run_py ([script , "-postarg" ])
541546 self .assertEqual ("PythonTestSuite" , data ["SearchInfo.company" ])
542547 self .assertEqual ("3.100-arm64" , data ["SearchInfo.tag" ])
543548 self .assertEqual (f"X.Y-arm64.exe -X fake_arg_for_test -prearg { script } -postarg" , data ["stdout" ].strip ())
544549
545550 def test_py_shebang_short_argv0 (self ):
546551 with self .py_ini (TEST_PY_COMMANDS ):
547- with self .script ("#! /usr/bin/env python -prearg" ) as script :
552+ with self .script ("#! /usr/bin/python -prearg" ) as script :
548553 # Override argv to only pass "py.exe" as the command
549554 data = self .run_py ([script , "-postarg" ], argv = f'"py.exe" "{ script } " -postarg' )
550555 self .assertEqual ("PythonTestSuite" , data ["SearchInfo.company" ])
551556 self .assertEqual ("3.100" , data ["SearchInfo.tag" ])
552557 self .assertEqual (f'X.Y.exe -prearg "{ script } " -postarg' , data ["stdout" ].strip ())
553558
559+ def test_search_path (self ):
560+ stem = Path (sys .executable ).stem
561+ with self .py_ini (TEST_PY_COMMANDS ):
562+ with self .script (f"#! /usr/bin/env { stem } -prearg" ) as script :
563+ data = self .run_py (
564+ [script , "-postarg" ],
565+ env = {"PATH" : f"{ Path (sys .executable ).parent } ;{ os .getenv ('PATH' )} " },
566+ )
567+ self .assertEqual (f"{ sys .executable } -prearg { script } -postarg" , data ["stdout" ].strip ())
568+
569+ def test_search_path_exe (self ):
570+ # Leave the .exe on the name to ensure we don't add it a second time
571+ name = Path (sys .executable ).name
572+ with self .py_ini (TEST_PY_COMMANDS ):
573+ with self .script (f"#! /usr/bin/env { name } -prearg" ) as script :
574+ data = self .run_py (
575+ [script , "-postarg" ],
576+ env = {"PATH" : f"{ Path (sys .executable ).parent } ;{ os .getenv ('PATH' )} " },
577+ )
578+ self .assertEqual (f"{ sys .executable } -prearg { script } -postarg" , data ["stdout" ].strip ())
579+
580+ def test_recursive_search_path (self ):
581+ stem = self .get_py_exe ().stem
582+ with self .py_ini (TEST_PY_COMMANDS ):
583+ with self .script (f"#! /usr/bin/env { stem } " ) as script :
584+ data = self .run_py (
585+ [script ],
586+ env = {"PATH" : f"{ self .get_py_exe ().parent } ;{ os .getenv ('PATH' )} " },
587+ )
588+ # The recursive search is ignored and we get normal "py" behavior
589+ self .assertEqual (f"X.Y.exe { script } " , data ["stdout" ].strip ())
590+
554591 def test_install (self ):
555592 data = self .run_py (["-V:3.10" ], env = {"PYLAUNCHER_ALWAYS_INSTALL" : "1" }, expect_returncode = 111 )
556593 cmd = data ["stdout" ].strip ()
0 commit comments