python / cpython

The Python programming language
https://www.python.org
Other
62.75k stars 30.08k forks source link

Python 3.11.0b4 - py launcher fails when running a script with a shebang line #94772

Closed pfmoore closed 2 years ago

pfmoore commented 2 years ago

Bug report

When running a script with a "shebang" line, the py.exe launcher in Python 3.11.0b4 fails with an error:

To reproduce, create the following script as x.py:

#!/usr/bin/env python
import sys
print(sys.version)
print(sys.executable)

Run the script using py.exe built from a 3.11.0b4 checkout using build.bat:

❯ .\amd64\py.exe .\x.py
 .\x.py': The system cannot find the file specified.ata\Local\Programs\Python\Python310\python.exe

Note the truncated python executable name. This appears to be related to the use of CRLF line endings in the file - if I switch to LF line endings, I get

❯ .\amd64\py.exe .\x.py
Unable to create process using 'C:\Users\Gustav\AppData\Local\Programs\Python\Python310\python.exe
 .\x.py': The system cannot find the file specified.

Your environment

pfmoore commented 2 years ago

OK, I just did a bisect, and found the bad commit was bad86a621af61f383b9f06fe4a08f66245df99e2 "bpo-46566: Add new py.exe launcher implementation (GH-32062)". Sigh, I suppose that should have been rather obvious 🙂

@zooba Any insights as to what's wrong here? As it's a complete new implementation, I don't honestly know where to look...

@pablogsal This is a fairly serious issue (assuming it's reproducible elsewhere and isn't somehow tied to something peculiar on my system), so it may warrant being labelled as a release blocker. Sorry!

pablogsal commented 2 years ago

Added release blocker label for 3.11.0b5

pfmoore commented 2 years ago

I just found out that there's debug logging in the launcher. Debug info:

❯ $env:PYLAUNCHER_DEBUG=1  
❯ .\amd64\py.exe C:\Work\Projects\cpython\PCbuild\x.py
argv0: C:\Work\Projects\cpython\PCbuild\amd64\py.exe
version: 3.11.0b4
# Read 74 bytes from C:\Work\Projects\cpython\PCbuild\x.py to find shebang line
Found shebang: /Shebang: /usr/bin/env python

# Reading from C:\Users\Gustav\AppData\Local\py.ini for commands/python
# Did not find file C:\Users\Gustav\AppData\Local\py.ini
# Reading from C:\Work\Projects\cpython\PCbuild\amd64\py.ini for commands/python
# Did not find file C:\Work\Projects\cpython\PCbuild\amd64\py.ini
# Treating shebang command 'python' as 'py'
# Reading from C:\Users\Gustav\AppData\Local\py.ini for defaults/py_python
# Did not find file C:\Users\Gustav\AppData\Local\py.ini
# Reading from C:\Work\Projects\cpython\PCbuild\amd64\py.ini for defaults/py_python
# Did not find file C:\Work\Projects\cpython\PCbuild\amd64\py.ini
SearchInfo.originalCmdLine: "C:\Work\Projects\cpython\PCbuild\amd64\py.exe" C:\Work\Projects\cpython\PCbuild\x.py
SearchInfo.restOfCmdLine:  C:\Work\Projects\cpython\PCbuild\x.py
SearchInfo.executablePath: (null)
SearchInfo.scriptFile: C:\Work\Projects\cpython\PCbuild\x.py
SearchInfo.executable: python.exe
SearchInfo.executableArgs:

SearchInfo.company: (null)
SearchInfo.tag: (empty)
SearchInfo.oldStyleTag: True
SearchInfo.lowPriorityTag: False
SearchInfo.exclude32Bit: False
SearchInfo.only32Bit: False
SearchInfo.allowDefaults: True
SearchInfo.allowExecutableOverride: True
SearchInfo.windowed: False
SearchInfo.list: False
SearchInfo.listPaths: False
SearchInfo.help: False
 -V:3.10          C:\Users\Gustav\AppData\Local\Programs\Python\Python310\python.exe
 -V:3.9           C:\Users\Gustav\AppData\Local\Programs\Python\Python39\python.exe
 -V:3.8           C:\Users\Gustav\AppData\Local\Programs\Python\Python38\python.exe
env.company: PythonCore
env.tag: 3.10
# about to run: C:\Users\Gustav\AppData\Local\Programs\Python\Python310\python.exe
 C:\Work\Projects\cpython\PCbuild\x.py
Unable to create process using 'C:\Users\Gustav\AppData\Local\Programs\Python\Python310\python.exe
 C:\Work\Projects\cpython\PCbuild\x.py': The system cannot find the file specified.
zooba commented 2 years ago

I'm going to assume it's an off-by-one error in this line or three lines down where we add 1 to calculate the length of the string.

Embarrassingly, the tests only test scripts with nothing after the shebang 🤦‍♂️ So adding a second line to the shebang tests will show the issue.

I probably won't get time to fix anything this week, so feel free, otherwise once I'm back at work I'll get to it.

pfmoore commented 2 years ago

Yes, that was it - good catch! I have a fix, but I can't test it against main because I'm getting build errors when I try to build there:

❯ .\build.bat
Using py -3.10 (found 3.10 with py.exe)
Fetching external libraries...
bzip2-1.0.8 already exists, skipping.
sqlite-3.38.4.0 already exists, skipping.
xz-5.2.5 already exists, skipping.
zlib-1.2.12 already exists, skipping.
Fetching external binaries...
libffi-3.4.2 already exists, skipping.
openssl-bin-1.1.1n already exists, skipping.
tcltk-8.6.12.1 already exists, skipping.
Finished.
Using "C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\msbuild.exe" (found in the Visual Studio installation)
Using py -3.10 (found 3.10 with py.exe)

C:\Work\Projects\cpython\PCbuild>"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\msbuild.exe" "C:\Work\Projects\cpython\PCbuild\pcbuild.proj" /t:Build /m /nologo /v:m /clp:summary /p:Configuration=Release /p:Platform=x64 /p:IncludeExternals=true /p:IncludeCTypes=true /p:IncludeSSL=true /p:IncludeTkinter=true /p:UseTestMarker= /p:GIT="C:\Users\Gustav\scoop\shims\git.exe"
  _iomodule.c
  bufferedio.c
  bytesio.c
  fileio.c
  iobase.c
  stringio.c
  textio.c
  winconsoleio.c
  _tracemalloc.c
  atexitmodule.c
  faulthandler.c
  gcmodule.c
  getbuildinfo.c
  getpath_noop.c
  posixmodule.c
  signalmodule.c
  abstract.c
  accu.c
  boolobject.c
  bytearrayobject.c
  bytes_methods.c
  bytesobject.c
  call.c
  capsule.c
  cellobject.c
  classobject.c
  codeobject.c
  complexobject.c
  descrobject.c
  dictobject.c
  enumobject.c
  exceptions.c
  fileobject.c
  floatobject.c
  frameobject.c
  funcobject.c
  genericaliasobject.c
  genobject.c
  interpreteridobject.c
  iterobject.c
  listobject.c
  longobject.c
  memoryobject.c
  methodobject.c
  moduleobject.c
  namespaceobject.c
  object.c
  obmalloc.c
  odictobject.c
  picklebufobject.c
  rangeobject.c
  setobject.c
  sliceobject.c
  structseq.c
  tupleobject.c
  typeobject.c
  unicodectype.c
  unicodeobject.c
  unionobject.c
  weakrefobject.c
  config_minimal.c
  msvcrtmodule.c
  winreg.c
  action_helpers.c
  myreadline.c
  parser.c
  peg_api.c
  pegen.c
  pegen_errors.c
  string_parser.c
  token.c
  tokenizer.c
  _freeze_module.c
  Python-ast.c
  Python-tokenize.c
  _warnings.c
  asdl.c
  ast.c
  ast_opt.c
  ast_unparse.c
  bltinmodule.c
  bootstrap_hash.c
  ceval.c
  codecs.c
  compile.c
  context.c
  dtoa.c
  dynload_win.c
  errors.c
  fileutils.c
  formatter_unicode.c
  frame.c
  future.c
  getargs.c
  getcompiler.c
  getcopyright.c
  getopt.c
  getplatform.c
  getversion.c
  hamt.c
  hashtable.c
  import.c
  importdl.c
  initconfig.c
  marshal.c
  modsupport.c
  mysnprintf.c
  mystrtoul.c
  pathconfig.c
  preconfig.c
  pyarena.c
  pyctype.c
  pyhash.c
  pylifecycle.c
  pymath.c
  pystate.c
  pystrcmp.c
  pystrhex.c
  pystrtod.c
  pythonrun.c
  pytime.c
  specialize.c
  structmember.c
  suggestions.c
  symtable.c
  thread.c
  traceback.c
  sysmodule.c
     Creating library C:\Work\Projects\cpython\PCbuild\win32\_freeze_module.lib and object C:\Work\Projects\cpython\PCb
  uild\win32\_freeze_module.exp
  _freeze_module.vcxproj -> C:\Work\Projects\cpython\PCbuild\win32\_freeze_module.exe
  Updated files: importlib._bootstrap.h, importlib._bootstrap_external.h, zipimport.h, abc.h, codecs.h, io.h, _collecti
  ons_abc.h, _sitebuiltins.h, genericpath.h, ntpath.h, posixpath.h, os.h, site.h, stat.h, importlib.util.h, runpy.h, __
  hello__.h, __phello__.h, __phello__.spam.h, frozen_only.h
  Updated files: getpath.h
  Killing any running python.exe instances...
  Regenerate opcode.h pycore_opcode.h opcode_targets.h
  Include\opcode.h regenerated from Lib\opcode.py
  Jump table written into Python\opcode_targets.h
  Generated sources are up to date
  Getting build info from C:\Users\Gustav\scoop\shims\git.exe
  Building heads/launcher_fix:7992168960 launcher_fix
  getpath.c
  _abc.c
  _bisectmodule.c
  blake2module.c
  blake2b_impl.c
  blake2s_impl.c
  _codecsmodule.c
  _collectionsmodule.c
  _contextvarsmodule.c
  _csv.c
  _functoolsmodule.c
  _heapqmodule.c
  _json.c
  _localemodule.c
  _lsprof.c
  _pickle.c
  _randommodule.c
  sha3module.c
  sre.c
  _stat.c
  _struct.c
  _weakref.c
  arraymodule.c
  atexitmodule.c
  audioop.c
  cmathmodule.c
  _datetimemodule.c
  errnomodule.c
  faulthandler.c
  gcmodule.c
  getbuildinfo.c
  itertoolsmodule.c
  main.c
  mathmodule.c
  md5module.c
  mmapmodule.c
  _opcode.c
  _operator.c
  posixmodule.c
  rotatingtree.c
  sha1module.c
  sha256module.c
  sha512module.c
  signalmodule.c
  _statisticsmodule.c
  symtablemodule.c
  _threadmodule.c
  _tracemalloc.c
  _typingmodule.c
  timemodule.c
  xxsubtype.c
  _xxsubinterpretersmodule.c
  fileio.c
  bytesio.c
  stringio.c
  bufferedio.c
  iobase.c
  textio.c
  winconsoleio.c
  _iomodule.c
  _codecs_cn.c
  _codecs_hk.c
  _codecs_iso2022.c
  _codecs_jp.c
  _codecs_kr.c
  _codecs_tw.c
  multibytecodec.c
  _winapi.c
  abstract.c
  accu.c
  boolobject.c
  bytearrayobject.c
  bytes_methods.c
  bytesobject.c
  call.c
  capsule.c
  cellobject.c
  classobject.c
  codeobject.c
  complexobject.c
  descrobject.c
  dictobject.c
  enumobject.c
  exceptions.c
  fileobject.c
  floatobject.c
  frameobject.c
  funcobject.c
  genericaliasobject.c
  genobject.c
  interpreteridobject.c
  iterobject.c
  listobject.c
  longobject.c
  memoryobject.c
  methodobject.c
  moduleobject.c
  namespaceobject.c
  object.c
  obmalloc.c
  odictobject.c
  picklebufobject.c
  rangeobject.c
  setobject.c
  sliceobject.c
  structseq.c
  tupleobject.c
  typeobject.c
  unicodectype.c
  unicodeobject.c
  unionobject.c
  weakrefobject.c
  myreadline.c
  tokenizer.c
  token.c
  pegen.c
  pegen_errors.c
  action_helpers.c
  parser.c
  string_parser.c
  peg_api.c
  invalid_parameter_handler.c
  winreg.c
  config.c
  msvcrtmodule.c
  pyhash.c
  _warnings.c
  asdl.c
  ast.c
  ast_opt.c
  ast_unparse.c
  bltinmodule.c
  bootstrap_hash.c
  ceval.c
  codecs.c
  compile.c
  context.c
  dynamic_annotations.c
  dynload_win.c
  errors.c
  fileutils.c
  formatter_unicode.c
  frame.c
  frozen.c
  future.c
  getargs.c
  getcompiler.c
  getcopyright.c
  getopt.c
  getplatform.c
  getversion.c
  hamt.c
  hashtable.c
  import.c
  importdl.c
  initconfig.c
  marshal.c
  modsupport.c
  mysnprintf.c
  mystrtoul.c
  pathconfig.c
  preconfig.c
  pyarena.c
  pyctype.c
  pyfpe.c
  pylifecycle.c
  pymath.c
  pytime.c
  pystate.c
  pystrcmp.c
  pystrhex.c
  pystrtod.c
  dtoa.c
  Python-ast.c
  Python-tokenize.c
  pythonrun.c
  specialize.c
  suggestions.c
  structmember.c
  symtable.c
  thread.c
  traceback.c
  deepfreeze.c
  zlibmodule.c
  adler32.c
  compress.c
  crc32.c
  infback.c
  inffast.c
  inflate.c
  inftrees.c
  trees.c
  uncompr.c
  zutil.c
  dl_nt.c
C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(48335,14): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Include\internal\pycore_global_strings.h(54): message : see declaration of '<unnamed-tag>' [C:
\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(48436,17): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Include\internal\pycore_global_strings.h(54): message : see declaration of '<unnamed-tag>' [C:
\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(48437,21): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Include\internal\pycore_global_strings.h(54): message : see declaration of '<unnamed-tag>' [C:
\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(52201,14): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Include\internal\pycore_global_strings.h(54): message : see declaration of '<unnamed-tag>' [C:
\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(52297,14): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Include\internal\pycore_global_strings.h(54): message : see declaration of '<unnamed-tag>' [C:
\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]

Build FAILED.

C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(48335,14): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(48436,17): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(48437,21): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(52201,14): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
C:\Work\Projects\cpython\Python\deepfreeze\deepfreeze.c(52297,14): error C2039: '_zipimporter': is not a member of '<un
named-tag>' [C:\Work\Projects\cpython\PCbuild\pythoncore.vcxproj]
    0 Warning(s)
    5 Error(s)

Time Elapsed 00:00:19.27

I'm not sure what to do about this. I can submit a PR, and simply hope that it has no issues (or at least that CI or the buildbots will catch any that do exist).

I did build the same change against 3.11.0b4 and ran the test suite, but I'm getting failures there:

0:02:35 [ 73/436/1] test_codecs
Windows fatal exception: access violation

Current thread 0x00018a08 (most recent call first):
  File "C:\Work\Projects\cpython\Lib\encodings\zlib_codec.py", line 15 in zlib_encode
  File "C:\Work\Projects\cpython\Lib\test\test_codecs.py", line 2796 in test_binary_to_text_denylists_binary_transforms
  File "C:\Work\Projects\cpython\Lib\unittest\case.py", line 579 in _callTestMethod
  File "C:\Work\Projects\cpython\Lib\unittest\case.py", line 623 in run
  File "C:\Work\Projects\cpython\Lib\unittest\case.py", line 678 in __call__
  File "C:\Work\Projects\cpython\Lib\unittest\suite.py", line 122 in run
  File "C:\Work\Projects\cpython\Lib\unittest\suite.py", line 84 in __call__
  File "C:\Work\Projects\cpython\Lib\unittest\suite.py", line 122 in run
  File "C:\Work\Projects\cpython\Lib\unittest\suite.py", line 84 in __call__
  File "C:\Work\Projects\cpython\Lib\unittest\suite.py", line 122 in run
  File "C:\Work\Projects\cpython\Lib\unittest\suite.py", line 84 in __call__
  File "C:\Work\Projects\cpython\Lib\test\support\testresult.py", line 140 in run
  File "C:\Work\Projects\cpython\Lib\test\support\__init__.py", line 1095 in _run_suite
  File "C:\Work\Projects\cpython\Lib\test\support\__init__.py", line 1221 in run_unittest
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\runtest.py", line 276 in _test_module
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\runtest.py", line 312 in _runtest_inner2
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\runtest.py", line 355 in _runtest_inner
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\runtest.py", line 230 in _runtest
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\runtest.py", line 260 in runtest
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\main.py", line 450 in run_tests_sequential
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\main.py", line 564 in run_tests
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\main.py", line 742 in _main
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\main.py", line 701 in main
  File "C:\Work\Projects\cpython\Lib\test\libregrtest\main.py", line 763 in main
  File "C:\Work\Projects\cpython\Lib\test\__main__.py", line 2 in <module>
  File "<frozen runpy>", line 88 in _run_code
  File "<frozen runpy>", line 198 in _run_module_as_main

I'm afraid I don't have time right now to work out what's going on here. I assume it's probably something not right with my local setup (it's been a long time since I built CPython from source).

For now, I've created https://github.com/python/cpython/pull/94779 with the basic fix. I can try to find time to get my build environment working properly and then complete that PR. But if someone wants to take what's in that PR and make a proper PR in the meantime, I'm fine with that.

pfmoore commented 2 years ago

lol, the three existing tests for the shebang all use a "script" that is a single line with no terminating newline. So they all fail with the fix I've made.

On the assumption that we want to support files with just a shebang and no newline or content (I'm not sure why we do, but I'm not going to make that call...) I'll update my fix and add some tests for the case where there is a newline...

zooba commented 2 years ago

I mean, we want them all to work, but I'd definitely rather have files with content also work. There shouldn't be any reason that both can't work though, it just makes the logic for stripping off trailing \r\n characters a bit more complex.

New tests would be great.

pfmoore commented 2 years ago

Done, and the PR has passed CI. If you have a chance to review, that would be great.

BTW, I found the logic in that bit of code pretty hard to follow. I didn't change it because I wanted to just do the minimal change necessary, but would you be OK with a follow-up to make the code a bit more verbose but (hopefully!) clearer?