question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Expand globs in arguments on Windows?

See original GitHub issue

I’m using a variadic Path argument:

@click.command()
@click.argument(
    "paths", nargs=-1, type=click.Path(exists=True, dir_okay=False)
)
def whatever(paths)
   ...

When I run myprogram.py *.txt, then on unix of course it works, because the shell expands on the glob. But on Windows, glob expansion is the responsibility of the program being invoked, and click doesn’t appear to do it – even in a case like this where it has all the information needed to tell that glob expansion is appropriate. And click kind of has to do it, because click wants to validate the paths, and this has to happen after glob expansion – if I pass *.txt, it says Error: Invalid value for "paths": Path "*.txt" does not exist., and my code doesn’t even get invoked, so I can’t even fix up the globs myself, except by disabling all of click’s validation and then doing it all myself.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
njsmithcommented, Aug 24, 2018

Is there a way to signal that something glob-like isn’t a glob, like single quotes on Unix?

I’m not sure. In Windows, quote handling is also done in process (basically you just get a raw command line string and are free to do whatever with it), so in principle you could use quotes to disable globbing for specific arguments. But in Python, the quote handling happens early in interpreter startup, so you can’t see them in sys.argv. I guess if you’re really masochistic you could call GetCommandLine and try to reparse it, but i can’t imagine this working well given all the ways you python can be invoked (e.g. python -m mycli), plus it’d be a ton of fiddly work for unclear benefit.

Python’s glob module lets you use [] for quoting. (E.g., the pattern [*].txt matches the literal filename *.txt.) Not very intuitive, but it is possible, and I guess Windows users are used to weird edge cases when trying to use the cli to refer to files with * in the name?

One last thing I thought of. What happens when using invoke (for testing or for dispatching other commands) now? On Windows, invoke(args=["subcommand", "*.txt"]) would expand, but on Unix it wouldn’t, which I can see causing inconsistent behavior.

I don’t know enough about click and invoke to say anything useful here. (I’ve spent about an hour with click so far 😃.) Tough I guess you could make the argument that the behavior is inconsistent on the two platforms, intentionally so, and your tests should reflect that?

1reaction
asweigartcommented, Dec 10, 2019

Hello, I came here from the Black project, because running black *.py doesn’t work on Windows Command Prompt or PowerShell and I’ve traced the problem to how Click handles wildcards. Click not handling this results in wildcards simply not working on Windows for every program that uses Click, which seems like a large hole.

How can we safely tell that a name is a glob? There are other patterns besides *.

I think leaning on Python’s glob module is suitable enough for handling * and ? (njsmith is correct that [] isn’t used on Windows, but we’d get it for free with glob.) And anyways, let’s not let perfect be the enemy of good; even just getting some features working would be good. I just want black *.py to work on Windows.

What if the name comes from Bash and *.txt was actually the name of the file after expansion?

To reiterate njsmith, this would have to be a Windows-only feature. The * and ? characters are illegal to have in files on Windows anyway (I assume this is an NTFS thing.)

Do we also want to expand ~?

Nah. This isn’t a Windows command line idiom. It’d be easier to leave it unimplemented, given that glob also doesn’t implement it.

Anyway, my comments mostly reiterate what njsmith said. I’d just like to shed more light on this issue because “wildcards don’t work on Windows” seems like a pretty big deal for every program that uses Click.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is there any way to get the windows cmd shell to expand ...
Note if no arguments are specified then expanded_list will be set to all files in the current directory which may or may not...
Read more >
How to make program accept glob (wildcards) at command line?
Show activity on this post. The easiest way to do this is to convert the command line parameter into a regular expression. See...
Read more >
ftp glob | Microsoft Learn
Reference article for the ftp glob command, which toggles allowing wildcard expansion for local file names.
Read more >
glob - Greg's Wiki
"Glob" is the common name for a set of Bash features that match or expand specific types of patterns. Some synonyms for globbing...
Read more >
The best way to expand glob pattern? - Unix Stack Exchange
Just let it expand inside an array declaration's right side: ... is especially useful if you need to pass the glob pattern from...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found