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

Using uv run as a task runner #5903

Open
my1e5 opened this issue Aug 8, 2024 · 58 comments
Open

Using uv run as a task runner #5903

my1e5 opened this issue Aug 8, 2024 · 58 comments
Labels
enhancement New feature or improvement to existing functionality

Comments

@my1e5
Copy link
Contributor

my1e5 commented Aug 8, 2024

For those of us migrating over from Rye, one of its nice features is the built-in task runner using rye run and [tool.rye.scripts]. For example:

[tool.rye.scripts]
hello = "echo Hello from Rye!"
$ rye run hello
Hello from Rye!

It could have some more features - here is a selection of feature requests from the community:

A lot of these requested features are things that other 3rd party tools currently offer. I thought it might be useful to highlight a few other tools here, in particular because they also integrate with the pyproject.toml ecosystem and can be used with uv today.

  • Poe the Poet

    https://github.com/nat-n/poethepoet

    uv add --dev poethepoet
    
    [tool.poe.tasks]
    hello = "echo Hello from poe!"
    
    $ uv run poe hello
    Poe => echo Hello from 'poe!'
    Hello from poe!
    
  • taskipy

    https://github.com/taskipy/taskipy

    uv add --dev taskipy
    
    [tool.taskipy.tasks]
    hello = "echo Hello from taskipy!"
    
    $ uv run task hello
    Hello from taskipy!
    

Perhaps these can serve as some inspiration for a future uv run task runner and also in the meantime offer a solution for people coming over from Rye looking for a way to run tasks.

@chrisrodrigue
Copy link

Relevant comment from another issue: #5632 (comment)

@chrisrodrigue
Copy link

PDM supports this: https://pdm-project.org/latest/usage/scripts/

@charliermarsh charliermarsh added enhancement New feature or improvement to existing functionality preview Experimental behavior labels Aug 9, 2024
@charliermarsh
Copy link
Member

Yeah we plan to support something like this! We haven't spent time on the design yet.

@nikhilweee
Copy link

The pyproject standard already supports [project.scripts], so uv may not need to use its own table.
https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#creating-executable-scripts

@charliermarsh
Copy link
Member

[project.scripts] is a little different -- that's used to expose specific Python functions as executable scripts, and we do support that already.

@chrisrodrigue
Copy link

Perhaps naming this section tool.uv.tasks or tool.uv.aliases could help disambiguate that.

@nikhilweee
Copy link

nikhilweee commented Aug 10, 2024

Or maybe [tool.uv.run] to be consistent with the command uv run. Or we could even think about [tool.uv.commands].
I'm not a big fan of [tool.uv.scripts] since it conflicts with [project.scripts] and I myself got confused before.

@cdwilson
Copy link

This is the main thing I missed coming from hatch: https://hatch.pypa.io/dev/config/environment/overview/#scripts

@chrisrodrigue
Copy link

chrisrodrigue commented Aug 23, 2024

+1 to @nikhilweee suggestions. I think “command” reflects the intent/concept.

Hatch has an “environment” concept and supports running commands namespaced to an environment like so

hatch run test:cov

where “test” is a user-defined environment (with a dependency group) and “cov” is a user-defined command for that environment.

[tool.hatch.envs.test]
dependencies = [
 "pytest",
 "pytest-cov",
 "pytest-mock",
 "freezegun",
]

[tool.hatch.envs.test.scripts]
cov = 'pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=src'

[[tool.hatch.envs.test.matrix]]
python = ["3.8", "3.9", "3.10", "3.11", "3.12"]

I would be curious to hear the use cases of nesting dependency groups and commands into “environments” like this rather than defining them at the top-level (i.e. [tool.uv.commands]/[tool.uv.dev-dependencies]).

@pietroppeter
Copy link

since it has not been mentioned yet, adding as a possible inspiration for design of tasks also pixi: https://pixi.sh/latest/features/advanced_tasks/

@metaist
Copy link

metaist commented Aug 28, 2024

I happen to be writing a cross-project task runner that supports a bunch of formats (e.g. rye, pdm, package.json, Cargo.toml; even uv's workspace config).

For what it's worth, almost all python runners use tool.<name>.scripts for task config (presumably inspired by npm's package.json format), so it's somewhat of an easier upgrade path for people coming from other tools.

https://github.com/metaist/ds

@inoa-jboliveira
Copy link

Also related to this thread, I wish uvx was uv run instead of uv tool run when inside a project.

uv tool run seems like something you would do to play with a tool, like ruff. But then you will eventually uv add ruff --dev and forever keep writing uv run ruff check instead of uvx ruff check which won't respect the locked version and will be in different virtualenv. It also means the tool could be running on a different Python (does not apply to ruff, but any other python lib) and all sorts of weird stuff can happen.

I know uv run stuff is still short, but it could be 4 keystrokes shorter.

Regarding uv run being a task runner it means people will type it waaaaay more often than uv tool run.
I would appreciate a dedicated command like uvr

@zanieb
Copy link
Member

zanieb commented Sep 8, 2024

@inoa-jboliveira I opened a dedicated issue for that #7186

@nikhilweee
Copy link

Putting together some thoughts about semantics. This issue is about adding support for running arbitrary instructions specified in pyproject.toml. I deliberately use the term instruction to avoid using any of the other terms under consideration (command, tool, script, etc).

What do we call these instructions?

Lots of existing tools refer to them as "scripts".

  1. npm and yarn have first class support for scripts. Users can define them in package.json
  2. composer also uses the same term. Users can define them in composer.json
  3. pdm takes inspiration from npm and also uses the term scripts. Users can define them in [tool.pdm.scripts]
  4. rye follows suit. Custom scripts are defined in [tool.rye.scripts]
  5. hatch also uses the term scripts, although they are tied to environments. Defined in [tool.hatch.envs.<env>.scripts]

It seems advantageous to just go with the term "scripts" because it is the de-facto standard. As noted by another user #5903 (comment), this would also reduce friction for users coming to uv from other package managers. That said, this approach has a major flaw because it overlaps with the concept of entry points defined in [project.scripts]. Entry points expose certain python functions as executable scripts, but do not allow arbitrary commands. Furthermore, [project.scripts] has already been established in PEP-0621, as the official spec. So what about other terms?

Another option is to use the term "tasks"

  1. pixi uses the term "tasks". Users can define them in the [tasks] table in pixi.toml
  2. bundler uses rake tasks. Although it resembles entry points, sh is supported.
  3. grunt and gulp also use the term "tasks". Although they are task runners, not package managers.
  4. gradle uses the term "tasks", defined in build.gradle

Another option is to call them "executables". dart uses this term in pubspec.yaml

We could also use "commands", although I wasn't able to find existing tools which use this term.

After settling on a name, an obvious thing to do is to let users define instructions in the [tool.uv.<name>] table.

How do we invoke these instructions?

There are two options here.

  1. Overload existing uv run <instruction> (follows from npm run <script>)
  2. Add a new subcommand uv invoke / uv command / uv task

How should these instructions be specified?

PDM's documentation around user scripts is pretty evolved, with support for a bunch of features.

  1. cmd mode, shell mode, composite mode
  2. Specify env vars and env files for each script
  3. Specify working dir and site packages for each script
  4. Specify order of arguments
  5. Specify pre and post scripts
  6. call a function from a python script (entry point)

Rye has its own format, which is a subset of PDM features.

  1. Specify env vars and env files for each script
  2. chain multiple scripts one after the other
  3. call a function from a python script (entry point)

I hope this serves as a starter for discussing additional details for this feature.

@charliermarsh
Copy link
Member

(Nice comment, thank you!)

@Xdynix
Copy link

Xdynix commented Sep 10, 2024

One nice thing about PDM is that if a command is not recognized as a built-in, it is treated as pdm run. Thus, pdm foobar would be shorthand for pdm run foobar, which executes the command defined in [tool.pdm.scripts.foobar].

@gdamjan
Copy link

gdamjan commented Sep 10, 2024

IMHO, pdm has the most extensive support for these scripts and I would personally like to see the same support in uv too. And if so, best to support the same pyproject section too 😱. It's especially nice when one doesn't have to use any other tools like Makefiles (ugh).

Alas, one can argue that the pdm support for scripts is feature-creep for uv, in which case the rye model works too :)

@patrick91
Copy link

Furthermore, [project.scripts] has already been established in PEP-0621, as the official spec. So what about other terms?

I wonder if would be a good time to maybe standardise this? I don't know if a pep is required, but since we have some many package managers for python it would be nice if we can have one way to define these instructions

@phihung
Copy link

phihung commented Oct 23, 2024

Hi. I created a small, dependency-free tool to manage scripts directly from pyproject.toml:
https://github.com/phihung/tomlscript

I came across this thread after implementing my own solution… Silly me.
However, there are some differences in the API design between tomlscript and existing solutions, as well as features that may not make it into the official uv implementation.

I hope the following example can provide some useful ideas for the discussion.

Config Example

[tool.tomlscript]
# Start dev server ==> this line is the documentation of the command
dev = "uv run uvicorn --port {port:5001} myapp:app --reload"

# Linter and test 
test = """
uv run ruff check
uv run pytest --inline-snapshot=review
"""

# Generate pyi stubs (python function) ==> Execute python function
gen_pyi = "mypackage.typing:generate_pyi"

# Functions defined here can be reused across multiple commands
source = """
say_() {
    echo $1
}
"""

Usage

alias tom="uv run tom"  # alias tom="uvx tomlscript"

tom  # list commands
tom dev --port 8000
tom gen_pyi  --mode all  # execute python function with arguments

@strangemonad
Copy link

FWIW, I tried to capture some of my wish list here - https://notes.strangemonad.com/Some+thoughts+on+python+workspaces. It's a bit broader in scope than just the task runner aspect but touches on how I'd like to see task runner commands, multi-project workspaces and consistent lifecycle commands work nicely together

@harkabeeparolus
Copy link

Hi. I created a small, dependency-free tool to manage scripts directly from pyproject.toml: https://github.com/phihung/tomlscript

First of all, I have to say that I appreciate the effort, and the terse config style. 👍🏻 The syntax is perhaps a little too magical for my tastes, but it does look nice.

That said, I admire what I find to be a slightly terrifying YOLO implementation of _find_doc() and is_pyfunc(). 👀 Heuristics at their finest! Well done. 😁

@kasvtv
Copy link

kasvtv commented Nov 12, 2024

I believe this is one of the most major features that uv is missing that other projects do have.

Adding support for this would bridge a major part of the feature gap!

@ljtruong
Copy link

ljtruong commented Nov 14, 2024

To add to @Kludex comment, i have been using poe for ages, and still do with uv. An example from one of my current projects:

[tool.poe.tasks]
pre.cmd = "pre-commit run --all-files"
pre.help = "Run pre-commit checks"

mypy.cmd = "mypy . --strict"
mypy.help = "Run mypy checks"
format.help = "Format code with Ruff"
format.cmd = "ruff format ."
ruff.help = "Run Ruff checks"
ruff.cmd = "ruff check --output-format=concise ."

test.help = "Run tests using Pytest"
test.cmd = "pytest"
"test:watch".cmd = "ptw . --now --clear"
"test:watch".help = "Run tests using Pytest in watch mode"

changelog.cmd = "github-changelog-md"
changelog.help = "Generate a changelog"

Other projects have more entries for mkdocs and other tools.

Poe is quite well used, it seems that using [tool.uv.tasks] and similar task syntax would be elegant.

Thanks! I was using poethepoet for a while with poetry, didn't know I could use it in any pyproject.toml. This is enough for now

@AtticusZeller
Copy link

what's the downside of pure shell instead of task runners such as poe?

@Xdynix
Copy link

Xdynix commented Nov 14, 2024

what's the downside of pure shell instead of task runners such as poe?

Using pure shell might need to activate the Python environment each time. Like invoking source ./.venv/bin/activate each time opening the project. Or have to add uv run before many commands like uv run mypy ., uv run pre-commit ..., which is frustrating.

And using task runners can also create shorthand for long commands. Like using pdm lint for ruff check --fix && ruff format.

Indeed these can all be done by some other approaches, but these tasks are often project-related and makes more sense to store as part of project config. This also allows them to be shared with other collaborators.

@AtticusZeller
Copy link

Thank you for the comprehensive explanation!

It does help understand the benefits of task runners.

We've been pondering the choice between pure shell and task runners in my new Python template repo. Unfortunately, I chose pure shell in the end. I'd like to share my perspective to offer others additional insights:

Using pure shell might need to activate the Python environment each time (like invoking source ./.venv/bin/activate) each time opening the project, or having to add uv run before many commands like uv run mypy ., uv run pre-commit ..., which is frustrating.

  1. In local development, terminals opened in VSCode will automatically activate your venv after Python environment selection, so uv run and source ... are not needed in this scenario.

  2. For remote environments like GitHub CI, or when we need to manually activate the environment, a single uv run bash yourshell.sh is sufficient.

And using task runners can also create shorthand for long commands. Like using pdm lint for ruff check --fix && ruff format.

  1. Long commands can be auto-completed from your completion suggestions or command history with zsh plugins when running once.

  2. Multiple commands look cleaner, are easier to control, and can be extended or combined harmoniously in one shell script (like running lint or mypy before pytest). Writing dynamic execution logic in pyproject.toml, which is meant for static configuration, feels weird to me.

So in my opinion, using a task runner feels redundant.

@Xdynix
Copy link

Xdynix commented Nov 14, 2024

@AtticusZeller Yes, that's true. There is always multiple approaches to make life easier.

What I mind is that these methods require you to set up your environment separately (such as configuring IDE to recognize and automatically activate virtual environments, configuring shell auto-completion, etc.). Not everyone has the same configuration. Using a task runner can standardize it and make it independent of the environment.

This way, when I or anyone else checked out the repository in any environment, they only need to have uv installed (which only takes one line of command) to immediately get started with the development process (linting, testing, dev server, etc.). And don't have to copy-paste some long commands first.

Because of these requirements of my use case, the task runner is more attractive to me.

@AtticusZeller
Copy link

AtticusZeller commented Nov 14, 2024

@Xdynix Thank you for sharing your perspective!

I understand your point about standardization and ease of use. However, I'd like to offer a different views.

I believe this might be asking too much from uv. Here's why:

  1. Basic development skills like environment management, IDE configuration, and shell operations should be fundamental knowledge for team development. These are not just Python-specific skills, but universal tools that benefit all development work.

  2. These common development practices can easily solve the standardization problem: Team documentation for environment setup or Standard shell scripts

  3. These universal tools and skills are valuable beyond just Python projects, also can be applied to various development scenarios

  4. Instead of avoiding these basics and implementing task execution in pyproject.toml, wouldn't it be better to focus on building strong fundamental skills, or keep tools focused on their primary purposes

The current solution feels like over-packaging - binding script execution tightly with uv when these problems can be naturally solved through common development practices. While task runners are powerful, I believe keeping tools focused on their core responsibilities (like uv on package management) and addressing standardization through team practices is a more sustainable approach.

@Xdynix
Copy link

Xdynix commented Nov 14, 2024

@AtticusZeller (Just some off-topic chitchat)

A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.
-- https://docs.astral.sh/uv/

I thought that one selling point of uv was to solve all the needs of Python environment in one stop, not just package management.

Basic development skills like environment management, IDE configuration, and shell operations should be fundamental knowledge for team development.

I totally agree. But I don't really want to force other people's toolboxes, especially when it's an informal collaboration, such as an open source project, a lab course, etc. Some people like VS Code, some like PyCharm, not to mention vim users (and notepad users?). And I'm too lazy to maintain a set of documentation for each common tool. Therefore I prefer to provide only minimal but sufficient developer experience support.

@harkabeeparolus
Copy link

harkabeeparolus commented Nov 14, 2024

what's the downside of pure shell instead of task runners such as poe?

Here's the kicker for me -- Windows support. I'm in a mixed team with about half the people on Windows / Visual Studio (the old one, not VS Code), half on macOS with PyCharm or VS Code, and some funny people using Vim/Neovim on WSL or Linux proper. Sure, I can whip out some Makefiles and bash scripts, but they will not work reliably for all developers, on all environments.

One way to tackle this is with policy and tooling. We could force our team to all use Unix. Or we could use Vagrant.

But a better solution, in my opinion, is Python. It's already portable by design. The standard library pathlib, shutil, and subprocess.run are a little more verbose than shell scripts, but not by too much. Writing our project admin tasks in portable Python and baking them into pyproject.toml or another task runner just works. We've started using nox to build our projects instead of Makefiles for this reason.

@sisp
Copy link
Contributor

sisp commented Nov 14, 2024

uv offers a unified experience across all platforms, combining the aforementioned tools in a single binary, which is amazing. But IMHO, a task runner should be language-agnostic, allowing to join forces for its development and maintenance, having the same features in all projects no matter the language, and avoiding the need to learn a new tool (for essentially the same thing) for each language. A popular and powerful cross-platform task runner is Task, and it is also available as a Python package (merely shipping the compiled Go binary) to ease its installation in Python projects.

Although it appears convenient to have yet another task runner integrated with uv, I'd vote against it for the mentioned reasons.

@harkabeeparolus
Copy link

harkabeeparolus commented Nov 14, 2024

The current solution feels like over-packaging - binding script execution tightly with uv when these problems can be naturally solved through common development practices. While task runners are powerful, I believe keeping tools focused on their core responsibilities (like uv on package management) and addressing standardization through team practices is a more sustainable approach.

I absolutely do not agree that scripts or tasks would be "over-packaging".

(See also the previous overview by @nikhilweee.)

In other words -- scripts or task runner functionality is not over-packaging. It's standard and expected functionality in every other modern workflow packaging tool for Python. In fact, if uv could not offer user-definable tasks, or a plugin system, it would be worse than every other modern packaging tool in this regard.

@AtticusZeller
Copy link

AtticusZeller commented Nov 14, 2024

Rye has scripts built in (and uv is the successor/replacement for rye)... In fact, if uv could not offer user-definable tasks, or a plugin system, it would be worse than every other modern packaging tool in this regard.

I respectfully disagree with this perspective for several key reasons:

  1. Popularity ≠ Necessity

The prevalence of task runners in existing tools doesn't automatically justify their inclusion in new ones. This appears to fall into the "appeal to popularity" fallacy. Just because Rye, Hatch, PDM, and others implement task runners doesn't mean it's the optimal design choice.and task runner absolutely not denote modern

  1. Unix Philosophy and Practical Value

The Unix philosophy advocates for tools that do one thing and do it well. When we examine the practical value of built-in task runners because most "tasks" are simply command aliases that can be handled by shell scripts and when it comes to complex workflows often require proper build tools anyway,

Adding task running to uv would dilute its core responsibility of package and Project management while providing minimal practical benefit.

  1. Python vs Rust Context

...since Rye was intended to be a "cargo for Python"

This comparison overlooks crucial differences

Rust's ecosystem is built around a single, standardized toolchain,but Python's ecosystem is intentionally diverse, with different tools serving different needs, so forcing Cargo-like standardization onto Python goes against its philosophy of "we're all consenting adults here"

@wu-clan
Copy link

wu-clan commented Nov 14, 2024

People choose and judge tools based on practicality and applicability, rather than opinions. These opinions have no meaning, even if you vote, a very few people would refuse this feature

@bbkane
Copy link

bbkane commented Nov 14, 2024

Rust's ecosystem is built around a single, standardized toolchain,but Python's ecosystem is intentionally diverse, with different tools serving different needs, so forcing Cargo-like standardization onto Python goes against its philosophy of "we're all consenting adults here"

I'm excited about uv BECAUSE its one tool to "rule them all" for common Python build needs. I'm so tired of picking five or more tools to lint/format/build/package/etc a new project, and learning how to make them play nicely with each other, all the while knowing that these tools will likely evolve independently and I'll need to re-figure this when I update them. In addition, everyone else will choose a DIFFERENT five tools and if I want to contribute to their project I'll also learn how they do it. Please uv, save me from this!

I think running tasks is a common enough need that it would fit well into uv and be useful for most projects. Let me just learn uv way to do it. Of course, if a project needs a more specialized way to run tasks, they can use something else, but solve the common case of running command aliases...

@stan-dot
Copy link

there are one tools to rule them all broader than just for Python is the Task runner mentioned above by @sisp

A popular and powerful cross-platform task runner is Task, and it is also available as a Python package (merely shipping the compiled Go binary) to ease its installation in Python projects.

also solves the problem of combinatorial explosion when N tools are used, but even more powerfully, as beyond just Python ecosystem

@harkabeeparolus
Copy link

harkabeeparolus commented Nov 14, 2024

To Be, Or Not To Be

First, the uv team at Astral have already decided that they are going to add some kind of task runner:

@charliermarsh commented on Aug 9

Yeah we plan to support something like this! We haven't spent time on the design yet.

...So I do not think it's very helpful for anyone if we discuss our opinions for or against endlessly. I think the more constructive thing to do would be to help with the design.

Target Audience

There is indeed a diverse ecosystem of tools for Python, since it's an old language that predates modern workflow tools for other languages, such as cargo, npm, dotnet, et al.

All of this will continue to exist whether uv has a basic task runner or not. Senior Python developers can continue to deploy fancy customized toolchains for their teams or CI/CD.

However, for new Pythonistas, either students, or developers coming from newer language ecosystems such as .NET, Rust, or Javascript, it would be very helpful to have the mythical "Cargo for Python" or "One tool to rule them all". Read e.g. Rye's Philosophy and Vision for building "the one tool" that the majority of Pythonistas would use most of the time because it's the easy, obvious default. It won't solve every problem and corner case, perhaps, but it will cover most needs for mostly everyone most of the time.

The Zen Of Python

There should be one-- and preferably only one --obvious way to do it.

Building "the one tool" or "Cargo for Python" would be the obvious way to develop in Python. Of course there will be a diverse ecosystem of specialized tools for every situation... But the should be one obvious way to start, lint, format, test, build, and publish a normal open source Python project.

I think uv should become "the one tool", and I think that requires the same basic task running capabilities that all the other modern Python workflow tools have.

@zanieb
Copy link
Member

zanieb commented Nov 14, 2024

The open question for me is whether or not we should be building a general purpose task runner, i.e., designing some sort of DSL, or investing specifically in uv lint, uv format, and uv test. I see a general purpose task runner as sort of antithetical towards creating a consistent experience for these core workflows.

@zanieb
Copy link
Member

zanieb commented Nov 14, 2024

(While I think @harkabeeparolus has a great point that moving the design forward is the best way to help move this issue forward, I do think discussion on the goals of and motivation for a task runner are reasonable as they will help inform the design)

@zgana
Copy link

zgana commented Nov 15, 2024

I want to build on this point from @chrisrodrigue earlier in the thread. With Hatch, we can tie scripts to specific sets of dependencies, installed into separate environments. This can be much more general than lint, format, test. Two examples from my team's project template:

  • A docs environment with sphinx plus any extensions, and with helper scripts to build and preview the docs.
  • An interactive environment with an ipykernel dependency, with helper scripts to install/uninstall a kernel.

I'm not at all opposed to expressing these sorts of things with plain old shell scripts. What we're still missing in uv however (unless I am just out of date here) is a way to tie scripts to a specific dependency group or union of dependency groups.

@appenz
Copy link

appenz commented Nov 15, 2024

One more vote that this should be implemented.

I think there would be a lot of value for being able to define a default target that allows me to start a package without knowing anything about it. Most Node packages can be started with "npm run" and I do not have to know the name of the package or the main javascript file. With package managers likely being the default way how novice users will run python packages in the future, I think ease-of-use matters.

@inoa-jboliveira
Copy link

Hi everyone, this discussion is veering off course. If you’re not interested in the task runner, please consider downvoting the issue and moving on. I’ve explored the workarounds, but unfortunately, each one falls short in some way. Let’s avoid introducing philosophical debates about open source maintenance and stay focused on resolving the issue at hand. Thanks!

@dbohdan
Copy link

dbohdan commented Nov 20, 2024

I have suggestions conditional on uv implementing a task runner.

Poe the Poet sequences

I use Poe the Poet as my task runner with both Poetry and uv. Something I really like about Poe is how it handles sequence tasks. I haven't seen it in other Python task runners. You can have a failure in a sequence abort the sequence immediately, have no effect, or only change the exit code of poe later. This is very useful, e.g., for independent checks that can fail.

Here is how I use it in my website project. (The Lua is for Pandoc.)

[tool.poe.tasks.check]
sequence = ["format", "lint", "type", "format-lua", "lint-lua"]
help = "Format and run all static checks"
ignore_fail = "return_non_zero"

Starting with Poe

If uv implements a task runner, I would like it to have a similar feature to Poe's sequences. More broadly, my impression is that Poe has well-designed features absent in other Python task runners. Poe also seems to be the go-to task runner for Poetry users. Because of this, I think reimplementing Poe the Poet would be a good starting point for uv. The existing design of Poe could be refined as needed in the process, like how it happened with the Ruff formatter.

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

No branches or pull requests