Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

click.Path(resolve_path=True) does not resolve non-existing paths under Windows python<=3.9 #2466

Closed
dairiki opened this issue Mar 11, 2023 · 2 comments

Comments

@dairiki
Copy link

dairiki commented Mar 11, 2023

Under Windows, python<=3.9, arguments and parameters of type click.Path(resolve_path=True) are not resolved to an absolute path if they refer to non-existing locations.

This behavior started with PR #2094.
Python’s pathlib.Path.resolve() shares this same broken behavior: on Windows, python <= 3.9, Path("missing-file").resolve() == Path("file"); in other environments or with other python versions, Path("missing-file").resolve() correctly produces an absolute path (by prefixing "missing-file" with the current working directory).

Under Windows, with python<=3.9, this test script will fail (at least for me).

from pathlib import Path

import click
from click.testing import CliRunner


@click.command()
@click.argument("path", type=click.Path(resolve_path=True))
def app(path):
    print(path)


def test_resolve_arg():
    runner = CliRunner()
    with runner.isolated_filesystem():
        result = runner.invoke(app, ["missing-file"])
        assert Path(result.output.strip()).is_absolute()

Environment:

  • OS: Windows (only)
  • Python version: 3.7, 3.8, 3.9
  • Click version: >= 8.0.3
@davidism
Copy link
Member

Sounds like the fix is to upgrade Python to fix a bug in Python.

@dairiki
Copy link
Author

dairiki commented Mar 11, 2023

That sounds like a cop-out to me.

It's not always possible to upgrade Python version, and anyway, Click is used by many applications that themselves purport to support their use on Windows with python >= 3.7. If a Click feature (trivial as it may be) doesn't work for a subset of that "supported" space, it makes the feature worse than useless for such projects — use of such a feature means the application is subtly broken in some environments. ("Works everywhere but Windows" — the best kind of bug!)

AFAICT, Click purports to support python >= 3.7 on Windows. If it can be fixed easily in Click (so that Click behaves in the way its documentation claims it does), why not?

I think the fix might be as simple as replacing this:

rv = os.fsdecode(pathlib.Path(rv).resolve())

with

rv = os.fsdecode(pathlib.Path(rv).absolute().resolve())

(If a fix is not possible, the documentation12 should be updated to note that resolve_path does not always work correctly on Windows, python<=3.9, so that users will know not to rely on it if they are targeting that environment.)

Footnotes

  1. https://click.palletsprojects.com/en/8.1.x/parameters/#parameter-types

  2. https://click.palletsprojects.com/en/8.1.x/api/#click.Path

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 26, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants