-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Return error when running uvx with a .py script #11623
base: main
Are you sure you want to change the base?
Conversation
d477bb2
to
7a5208f
Compare
crates/uv/src/commands/tool/run.rs
Outdated
.extension() | ||
.is_some_and(|ext| ext.eq_ignore_ascii_case("py")) | ||
{ | ||
if possible_path.try_exists()? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we error if we can't read the path? (earnestly not sure here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good question. We could treat that as the "doesn't exist case" if we'd prefer.
crates/uv/src/commands/tool/run.rs
Outdated
)); | ||
} | ||
return Err(anyhow::anyhow!( | ||
"It looks like you are trying to run a script that doesn't exist. \n\n{}{} Did you mean `uvx {}`?", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems nice to include the script name, maybe like
It looks like you're trying to run a script (
{}
) but it does not exist.
Not in love with that, but don't have a better idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the "Did you mean" message, should we clarify what uvx <name>
would do? Like "Did you mean to run a tool with uvx {}
"?
I'm not sure if I prefer it, but wanted to put it out there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think adding that context is helpful
crates/uv/src/commands/tool/run.rs
Outdated
@@ -104,6 +105,26 @@ pub(crate) async fn run( | |||
return Err(anyhow::anyhow!("Tool command could not be parsed as UTF-8 string. Use `--from` to specify the package name.")); | |||
}; | |||
|
|||
let possible_path = Path::new(target); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If --from
is provided, e.g, uvx --from <package> foo.py
we should probably not perform this check as they've opted-in to loading a specific source.
We probably want to have this logic for uvx --from foo.py <command>
though? We can't give a good suggestion though since we don't support like uv run --with-requirements foo.py <command>
yet — see #6542
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to reflect your suggestion
crates/uv/src/commands/tool/run.rs
Outdated
.is_some_and(|ext| ext.eq_ignore_ascii_case("py") || ext.eq_ignore_ascii_case("pyw")) | ||
{ | ||
return Err(anyhow::anyhow!( | ||
"It looks you have passed a script instead of a package into `--from`" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use the same suggestion as below? (but with --from <package>
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't suggest uv run ...
but we can suggest uvx --from script-py ...
instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
crates/uv/src/commands/tool/run.rs
Outdated
)) | ||
} else { | ||
Err(anyhow::anyhow!( | ||
"It looks like you are trying to run a script that doesn't exist. \n\n{}{} Did you mean to run a tool with `uvx {}`?", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I missed this initially, you need to use invocation_source
here instead of hard-coding uvx
because that's an alias for uv tool run
(and we want to match what the user used)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
This looks good to me, thanks for addressing the feedback. I want to do one final pass on the messaging, since this is ostensibly breaking (though I really hope nobody is relying on this behavior). I'll do that on Monday. |
If we see
uvx script.py
, we exit early, giving a hint to useuv run script.py
if the script exists. If it does not exist, we suggest runninguv run
with a normalized package name.This PR includes a snapshot test for each of these scenarios.
An alternative approach would be to wait until we encounter an error, and then add the hint. But if there happens to be a malicious package called
script-py
, this would be run unintentionally (a point raised by @zanieb).Closes #10784