GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — shutil.which() can return non-executable path starting with 3.12 on Windows · Issue #127001 · python/cpython

shutil.which() can return non-executable path starting with 3.12 on Windows #127001

New issue
Copy link
New issue
Copy link
Closed
Closed
shutil.which() can return non-executable path starting with 3.12 on Windows#127001
Copy link
Assignees
serhiy-storchaka
Labels
3.12only security fixesonly security fixes3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixesOS-windowsstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@lazka
lazka
opened on Nov 19, 2024
Issue body actions

Bug report

Bug description:

Starting with Python 3.12 if a file is in PATH that does not end with PATHEXT, but happens to be named the same as the searched command it is returned instead of the real command later in PATH which includes PATHEXT.

# Assume:
# PATH=C:\foo;C:\WINDOWS\system32
# "C:\foo\cmd" exists
# "C:\WINDOWS\system32\cmd.exe" exists

import shutil
print(shutil.which('cmd'))
# Actual: C:\foo\cmd
# Expected: C:\WINDOWS\system32\cmd.exe (3.11 result)

I have verified that this change was introduced with #103179 and reverting it fixes the issue.

@csm10495 ^

Downstream context: mesonbuild/meson#13886

CPython versions tested on:

3.12

Operating systems tested on:

Windows

Linked PRs

  • gh-127001: Fix PATHEXT issues in shutil.which() on Windows #127035
  • [3.13] gh-127001: Fix PATHEXT issues in shutil.which() on Windows (GH-127035) #127156
  • [3.12] gh-127001: Fix PATHEXT issues in shutil.which() on Windows (GH-127035) #127158

Activity

  1. lazka
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Nov 19, 2024
  2. zooba commented on Nov 19, 2024

    @zooba
    zooba
    on Nov 19, 2024
    Member
    More actions

    Reverting the entire change is clearly not going to happen - the logic was incorrect before, and apparently is still incorrect, so let's figure out what correct logic for handling PATHEXT would be.

    Reacted by Christoph Reiter
  3. serhiy-storchaka commented on Nov 19, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Nov 19, 2024
    Member
    More actions

    Should not it be fixed by #109590?

  4. serhiy-storchaka commented on Nov 19, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Nov 19, 2024
    Member
    More actions

    Ah, it still checks for file without extension.

  5. lazka commented on Nov 19, 2024

    @lazka
    lazka
    on Nov 19, 2024
    ContributorAuthor
    More actions

    Should not it be fixed by #109590?

    That only handles the "in the same directory" case, and not in different directories, from what I see.

    But, that issue mentioned Get-Command cmd in powershell, which I now tried, and that also returns the wrong path as "CommandType=Application" here, even though the docs say that it only returns files ending with PATHEXT (https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/get-command?view=powershell-7.4#-commandtype) so I don't know what's "right" anymore :)

    PS C:\Users\user> echo $env:PATH
    C:\msys64\usr\bin;C:\Windows\System32;C:\Windows
    PS C:\Users\user> echo $env:PATHEXT
    .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL
    PS C:\Users\user> Get-Command cmd
    
    CommandType     Name                                               Version    Source
    -----------     ----                                               -------    ------
    Application     cmd                                                0.0.0.0    C:\msys64\usr\bin\cmd
    
    PS C:\Users\user> Get-Command -All cmd
    
    CommandType     Name                                               Version    Source
    -----------     ----                                               -------    ------
    Application     cmd                                                0.0.0.0    C:\msys64\usr\bin\cmd
    Application     cmd.exe                                            10.0.2610… C:\Windows\System32\cmd.exe
  6. serhiy-storchaka
    self-assigned this
    on Nov 19, 2024
  7. serhiy-storchaka
    added
    3.12only security fixesonly security fixes
    3.13only security fixesonly security fixes
    3.14bugs and security fixesbugs and security fixes
    OS-windows
    on Nov 19, 2024
  8. zooba commented on Nov 19, 2024

    @zooba
    zooba
    on Nov 19, 2024
    Member
    More actions

    The right behaviour ought to be "whatever CreateProcess("cmd") would run". Terminals all layer their own logic on top, but Python tries to generally stick to the closest public API that implements the functionality.

    (One explicit exception we make to CreateProcess behaviour is that we don't search the application directory first with which, because if we did, it wouldn't be useful. By skipping that somewhat strange edge case, it is possible to use which to override the application directory. This mainly only matters for python.exe - CreateProcess("python") will always launch sys._base_executable due to how the API works, but CreateProcess(shutil.which("python")) follows PATH, which is likely what was intended if a user provided the command name.)

  9. serhiy-storchaka
    added a commit that references this issue on Nov 19, 2024

    pythongh-127001: Fix conflict with extensionless files in shutil.whic…

    b2ec0f6
  10. lazka commented on Nov 19, 2024

    @lazka
    lazka
    on Nov 19, 2024
    ContributorAuthor
    More actions

    The right behaviour ought to be "whatever CreateProcess("cmd") would run". Terminals all layer their own logic on top, but Python tries to generally stick to the closest public API that implements the functionality.

    Also CreateProcess prefers "C:\Windows\System32" over PATH, like curl/tar/bash that are in there, which is another can of worms :(

    Since my initial presented scenario occurs in MSYS2, and it's not quite clear why we have that "cmd" bash script in PATH in the first place, I'm trying to get rid of it instead now :/

    Reacted by Steve Dower
  11. csm10495 commented on Nov 21, 2024

    @csm10495
    csm10495
    on Nov 21, 2024
    Contributor
    More actions

    Ouch. Sorry for the regression folks. I wish this was less complicated than it is. I see @serhiy-storchaka has already started on a fix. Thanks all.

  12. picnixz
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Nov 21, 2024
  13. serhiy-storchaka commented on Nov 22, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Nov 22, 2024
    Member
    More actions

    There was other bug introduced in #109995: full match did not work for files with multcomponent extension in PATHEXT, (e.g. .foo.bar).

    Other corner case was only discussed in comments: a dot (.) in PATHEXT.

  14. serhiy-storchaka
    added a commit that references this issue on Nov 22, 2024

    gh-127001: Fix PATHEXT issues in shutil.which() on Windows (GH-127035)

    8899e85
  15. miss-islington
    added a commit that references this issue on Nov 22, 2024

    pythongh-127001: Fix PATHEXT issues in shutil.which() on Windows (pyt…

    068f56f
  16. serhiy-storchaka
    added 3 commits that reference this issue on Nov 22, 2024

    [3.12] pythongh-127001: Fix PATHEXT issues in shutil.which() on Windo…

    3dfcf12

    [3.13] gh-127001: Fix PATHEXT issues in shutil.which() on Windows (GH…

    7f22b87

    [3.12] gh-127001: Fix PATHEXT issues in shutil.which() on Windows (GH…

    2964898
  17. serhiy-storchaka
    closed this as completedon Nov 22, 2024
  18. lazka commented on Nov 22, 2024

    @lazka
    lazka
    on Nov 22, 2024
    ContributorAuthor
    More actions

    I can confirm that this fixes things for my use case. Thanks everyone!

  19. facsimiles-push
    added a commit that references this issue on Nov 25, 2024

    CI: fix: re-instate 'gvmap.sh' detection skipping on MinGW

    b956911
  20. eabase commented on Dec 14, 2024

    @eabase
    eabase
    on Dec 14, 2024
    More actions

    This got to be the best issue number in all of internet!
    127.0.0.1

    Reacted by Christoph Reiter and Kagami Sascha Rosylight
  21. ebonnal
    added a commit that references this issue on Jan 12, 2025

    pythongh-127001: Fix PATHEXT issues in shutil.which() on Windows (pyt…

    61713b2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @serhiy-storchaka
    serhiy-storchaka

Labels

3.12only security fixesonly security fixes3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixesOS-windowsstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.