Bob Alexander added the comment:

Since there seems to be ongoing work on the "which"
function, here are a few more thoughts on this function's

  - The existing version does not prepend the current
    directory to the path if it is already in the path.
    If the current directory is in the path but is not
    the first element, it will not be the first directory
    searched. It seems that the desired behavior is to
    search the current directory first, so the current
    directory should *always* be prepended. The existing
    "which" function already has an optimization to only
    search each directory once, so it's not a problem if
    the current directory is unconditionally prepended
    and may end up in there twice. This change would
    actually be a "correction", since the doc says the
    current directory is prepended

  - The function should always return an absolute path,
    which is the behavior of the Unix(1) "which" command
    and, I think, is the typical expected behavior of a
    "which"-type request. The existing implementation
    returns a relative path in certain cases, such as if
    the file is found via a relative directory reference
    in the path. This change is not inconsistent with
    the doc, since the doc does not address it.

  - It would be nice if the extension added when the
    given command has no extension were lower case,
    instead of the upper case extension retrieved from
    the PATHEXT environment variable. Several other
    "which" implementations work that way (e.g.
    see Go's os/exec.LookPath function), producing
    a more aesthetically pleasing name, as well as
    being more consistent with naming practices of the
    last 20+ years. The shocking-looking upper case
    sxtensions remind me of VERY OLD DOS programs  :-)
    This presents no conflict with the doc, and does
    not affect "correctness" since Windows file names
    are case-independent.

    A previous commenter objected to adding lower case
    extensions, but consider:
      - The current version never returns the extension
        case of the actual file. It returns the extension
        of the command string passed to the function,
        if any, otherwise it adds the extension from the
        PATHEXT environment variable, either of which
        might not match the actual file.
      - Returning the actual extension of the found file
        might be nice, but would require additional I/O;
        added expense for little return. This is not
        done in the current version.
      - The PATHEXT variable that ships with Windows
        contains the allowable extensions in upper case,
        an old DOS artifact. Few executable files these
        days have uppercase extensions. Using a lower
        case extension when the function has to invent
        one is a "modernization".

  - It would be nice if the returned file path were
    normalized. Currently, sometimes an unnormalized
    path is returned with a leading ".\".

I did write an update to "which" with the above changes,
and also updated the unit tests with:
  - 2 new tests to catch the bug that is the subject of
    this issue.
  - some tests were updated for the small changes such
    as normalization and lower case added extensions.
A zip file is attached with my updates. I'm not an
official "contributor", but feel free incorporate the
contents in any way you deem appropriate. The files are:
    updated shutil module
    existing 3.5.1 shutil module -- basis for updates
    unit tests for existing 3.5.1 version of shutil with
    new tests to catch this bug
    unit tests for attached updated version of shutil
    existing 3.5.1 unit tests -- basis for updates


Added file:

Python tracker <>
Python-bugs-list mailing list

Reply via email to