Skip to content

Comments

Support --with-requirements script.py and -r script.py to include inline dependency metadata from another script#12763

Merged
zanieb merged 16 commits intoastral-sh:mainfrom
blueraft:uvx-with-requirements-scripts
Sep 5, 2025
Merged

Support --with-requirements script.py and -r script.py to include inline dependency metadata from another script#12763
zanieb merged 16 commits intoastral-sh:mainfrom
blueraft:uvx-with-requirements-scripts

Conversation

@blueraft
Copy link
Contributor

@blueraft blueraft commented Apr 8, 2025

Summary

Closes #6542

Test Plan

cargo test

@zanieb
Copy link
Member

zanieb commented Apr 8, 2025

That was more straight-forward than I assumed! I think we'll need to align on the interface.

@T-256
Copy link
Contributor

T-256 commented Apr 9, 2025

@zanieb
Copy link
Member

zanieb commented May 15, 2025

@blueraft I wonder if we can push this forward? I think support in --with-requirements might make sense still, given we read a bunch of other file types there. I wonder if we can just sniff for a PEP 723 inline metadata entry in the script if there's no file extension?

@blueraft
Copy link
Contributor Author

I wonder if we can just sniff for a PEP 723 inline metadata entry in the script if there's no file extension?

Yeah, I think we could do that. Let me give that a try!

@blueraft blueraft force-pushed the uvx-with-requirements-scripts branch 3 times, most recently from 76e0820 to 0cf1c92 Compare May 16, 2025 09:02
Comment on lines 1169 to 1178
let pep723_results = join_all(
args.with_requirements
.iter()
.filter(|file| is_pep723_candidate(file))
.map(|file| async move {
let result = Pep723Script::read(&file).await;
(file, result)
}),
)
.await;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry if this is something we've talked about before (trying to pick this back up now), but why are we doing all this here instead of in RequirementsSource::from_requirements_file? It feels weird to parse these eagerly then filter them from the subsequent call?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, RequirementsSource::from_requirements_file is used in a bunch of places, but we may not want to support reading requirements from a PEP723 script in all of those instances. I guess we could pass a flag to that function whether to accept PEP723 scripts or not but no strong preference there

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I think I probably would expect it to support PEP 723 scripts everywhere, e.g., --with-requirements <path> being equivalent to pip install -r <path> and pip compile <path>. I wonder if there are edge-cases where we wouldn't want it? Like -r script.py inside a requirements.txt file? Do we already allow -r pyproject.toml inside requirements.txt files? If so, I guess this would be fine?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--with-requirements <path> being equivalent to pip install -r <path>

Does this mean we would also support uv pip install -r script.py?

Do we already allow -r pyproject.toml inside requirements.txt files?

This doesn't seem to be supported

❯ cat requirements.txt
-r pyproject.toml
flask
❯ uv pip install -r requirements.txt
error: Error parsing included file in `requirements.txt` at position 0
  Caused by: Unexpected '[', expected '-c', '-e', '-r' or the start of a requirement at pyproject.toml:1:1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we would also support uv pip install -r script.py?

Yeah, I think so. I think it'd be inconsistent otherwise, and I'm not sure why we shouldn't support it.

This doesn't seem to be supported

Thank goodness :) though I'm confused by that error message 🤔

@blueraft blueraft marked this pull request as draft August 15, 2025 16:54
bail!("Adding requirements from a `setup.py` is not supported in `uv add`");
}
RequirementsSource::Pep723Script(_) => {
bail!("Adding requirements from a PEP723 script is not supported in `uv add`");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bail!("Adding requirements from a PEP723 script is not supported in `uv add`");
bail!("Adding requirements from a PEP 723 script is not supported in `uv add`");

Copy link
Member

@zanieb zanieb Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably could support this fwiw — it seems less confusing than importing from another project. It seems good to wait until there's a clear use-case though.

Ok(Some(script)) => Pep723Item::Script(script),
Ok(None) => {
return Err(anyhow::anyhow!(
"`{}` does not contain a PEP 723 metadata tag; run `{}` to initialize the script",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably omit the run ... to initialize hint. That belongs outside the error message. The dependencies would be empty too, so it'd have no meaningful effect for this kind of usage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

----- stdout -----

----- stderr -----
error: `not_pep723_script.py` does not contain a PEP 723 metadata tag; run `uv init --script not_pep723_script.py` to initialize the script
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should just say "script metadata tag"? I generally don't want the specification to be a user-facing concept and prefer to refer to "inline script metadata".

@blueraft blueraft changed the title Support --with-requirements script.py to include inline dependency metadata from another script Support --with-requirements script.py and -r script.py to include inline dependency metadata from another script Aug 18, 2025
@blueraft blueraft marked this pull request as ready for review August 18, 2025 19:38
Ok(Some(script)) => Pep723Item::Script(script),
Ok(None) => {
return Err(anyhow::anyhow!(
"`{}` does not contain an inline script metadata tag.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"`{}` does not contain an inline script metadata tag.",
"`{}` does not contain inline script metadata",

Just bike-shedding the message, but note we don't end with a period for single sentence errors..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@zanieb zanieb merged commit 6eefde2 into astral-sh:main Sep 5, 2025
230 of 242 checks passed
@zanieb
Copy link
Member

zanieb commented Sep 5, 2025

Thank you so much for your patience here!

@zanieb zanieb added the enhancement New feature or improvement to existing functionality label Sep 5, 2025
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Sep 12, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.8.15` -> `0.8.17` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>astral-sh/uv (astral-sh/uv)</summary>

### [`v0.8.17`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0817)

[Compare Source](astral-sh/uv@0.8.16...0.8.17)

Released on 2025-09-10.

##### Enhancements

- Improve error message for HTTP validation in auth services ([#&#8203;15768](astral-sh/uv#15768))
- Respect `PYX_API_URL` when suggesting `uv auth login` on 401 ([#&#8203;15774](astral-sh/uv#15774))
- Add pyx as a supported PyTorch index URL ([#&#8203;15769](astral-sh/uv#15769))

##### Bug fixes

- Avoid initiating login flow for invalid API keys ([#&#8203;15773](astral-sh/uv#15773))
- Do not search for a password for requests with a token attached already ([#&#8203;15772](astral-sh/uv#15772))
- Filter pre-release Python versions in `uv init --script` ([#&#8203;15747](astral-sh/uv#15747))

### [`v0.8.16`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0816)

[Compare Source](astral-sh/uv@0.8.15...0.8.16)

##### Enhancements

- Allow `--editable` to override `editable = false` annotations ([#&#8203;15712](astral-sh/uv#15712))
- Allow `editable = false` for workspace sources ([#&#8203;15708](astral-sh/uv#15708))
- Show a dedicated error for virtual environments in source trees on build ([#&#8203;15748](astral-sh/uv#15748))
- Support Android platform tags ([#&#8203;15646](astral-sh/uv#15646))
- Support iOS platform tags ([#&#8203;15640](astral-sh/uv#15640))
- Support scripts with inline metadata in `--with-requirements` and `--requirements` ([#&#8203;12763](astral-sh/uv#12763))

##### Preview features

- Support `--no-project` in `uv format` ([#&#8203;15572](astral-sh/uv#15572))
- Allow `uv format` in unmanaged projects ([#&#8203;15553](astral-sh/uv#15553))

##### Bug fixes

- Avoid erroring when `match-runtime` target is optional ([#&#8203;15671](astral-sh/uv#15671))
- Ban empty usernames and passwords in `uv auth` ([#&#8203;15743](astral-sh/uv#15743))
- Error early for parent path in build backend ([#&#8203;15733](astral-sh/uv#15733))
- Retry on IO errors during HTTP/2 streaming ([#&#8203;15675](astral-sh/uv#15675))
- Support recursive requirements and constraints inclusion ([#&#8203;15657](astral-sh/uv#15657))
- Use token store credentials for `uv publish` ([#&#8203;15759](astral-sh/uv#15759))
- Fix virtual environment activation script compatibility with latest nushell ([#&#8203;15272](astral-sh/uv#15272))
- Skip Python interpreters that cannot be queried with permission errors ([#&#8203;15685](astral-sh/uv#15685))

##### Documentation

- Clarify that `uv auth` commands take a URL ([#&#8203;15664](astral-sh/uv#15664))
- Improve the CLI help for options that accept requirements files ([#&#8203;15706](astral-sh/uv#15706))
- Adds example for caching for managed Python downloads in Docker builds ([#&#8203;15689](astral-sh/uv#15689))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS45OC4xIiwidXBkYXRlZEluVmVyIjoiNDEuOTkuNiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90Il19-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or improvement to existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support --with-requirements script.py to include inline dependency metadata from another script

7 participants