Given a command, mode, and a PATH string, return the path which conforms to the given mode on the PATH, or None if there is no such file. `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result of os.environ.get("PATH"), or can be overridden with a custom search path
(cmd, mode=os.F_OK | os.X_OK, path=None)
| 1576 | |
| 1577 | |
| 1578 | def which(cmd, mode=os.F_OK | os.X_OK, path=None): |
| 1579 | """Given a command, mode, and a PATH string, return the path which |
| 1580 | conforms to the given mode on the PATH, or None if there is no such |
| 1581 | file. |
| 1582 | |
| 1583 | `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result |
| 1584 | of os.environ.get("PATH"), or can be overridden with a custom search |
| 1585 | path. |
| 1586 | |
| 1587 | """ |
| 1588 | use_bytes = isinstance(cmd, bytes) |
| 1589 | |
| 1590 | # If we're given a path with a directory part, look it up directly rather |
| 1591 | # than referring to PATH directories. This includes checking relative to |
| 1592 | # the current directory, e.g. ./script |
| 1593 | dirname, cmd = os.path.split(cmd) |
| 1594 | if dirname: |
| 1595 | path = [dirname] |
| 1596 | else: |
| 1597 | if path is None: |
| 1598 | path = os.environ.get("PATH", None) |
| 1599 | if path is None: |
| 1600 | try: |
| 1601 | path = os.confstr("CS_PATH") |
| 1602 | except (AttributeError, ValueError): |
| 1603 | # os.confstr() or CS_PATH is not available |
| 1604 | path = os.defpath |
| 1605 | # bpo-35755: Don't use os.defpath if the PATH environment variable |
| 1606 | # is set to an empty string |
| 1607 | |
| 1608 | # PATH='' doesn't match, whereas PATH=':' looks in the current |
| 1609 | # directory |
| 1610 | if not path: |
| 1611 | return None |
| 1612 | |
| 1613 | if use_bytes: |
| 1614 | path = os.fsencode(path) |
| 1615 | path = path.split(os.fsencode(os.pathsep)) |
| 1616 | else: |
| 1617 | path = os.fsdecode(path) |
| 1618 | path = path.split(os.pathsep) |
| 1619 | |
| 1620 | if sys.platform == "win32" and _win_path_needs_curdir(cmd, mode): |
| 1621 | curdir = os.curdir |
| 1622 | if use_bytes: |
| 1623 | curdir = os.fsencode(curdir) |
| 1624 | path.insert(0, curdir) |
| 1625 | |
| 1626 | if sys.platform == "win32": |
| 1627 | # PATHEXT is necessary to check on Windows. |
| 1628 | pathext_source = os.getenv("PATHEXT") or _WIN_DEFAULT_PATHEXT |
| 1629 | pathext = pathext_source.split(os.pathsep) |
| 1630 | pathext = [ext.rstrip('.') for ext in pathext if ext] |
| 1631 | |
| 1632 | if use_bytes: |
| 1633 | pathext = [os.fsencode(ext) for ext in pathext] |
| 1634 | |
| 1635 | files = [cmd + ext for ext in pathext] |
no test coverage detected
searching dependent graphs…