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

alternatives to poe #216

Open
jorenham opened this issue Nov 28, 2024 · 20 comments
Open

alternatives to poe #216

jorenham opened this issue Nov 28, 2024 · 20 comments

Comments

@jorenham
Copy link
Owner

jorenham commented Nov 28, 2024

@miloth pointed out in #174 (comment) why we should consider replacing poe as task runner, and suggests just as an alternative.

Going back to the choice between poe and just. I believe using Python as a command runner is a bit unnecessary. You are adding the complexity of an additional layer of interpreter for no added benefit. I prefer just, as it is a compiled tool, so much more self-contained. In the end though, the commands specified here are quite simple, so the choice will not have a massive impact. In the end, the uv team are considering their own command runner, so it could all end up under one tool anyways.

Considering the plan to migrate from poetry to uv (#49), I believe this makes sense.

But there are several other alternative task runners that could be worth considering:

Personally I have no experience with any of the the task runners, and don't know what their advantages are. So if anyone is willing to share their thoughts on this, that would help a lot :)

@jorenham jorenham added the meta: DX Developer experience label Nov 28, 2024
@jorenham
Copy link
Owner Author

Any thoughts on this, @wolph?

@lucascolley
Copy link
Contributor

probably no reason to use pixi for tasks unless you are going to use it for package management also. But if you end up wanting to use Conda packages instead of PyPI, pixi is a no-brainer for both package management and tasks IMO.

@jorenham
Copy link
Owner Author

probably no reason to use pixi for tasks unless you are going to use it for package management also. But if you end up wanting to use Conda packages instead of PyPI, pixi is a no-brainer for both package management and tasks IMO.

Ah alright. I think that uv then indeed makes more sense for this project. I'm not very familiar with Conda either, and optype is only published on PyPI.

I was, however, thinking of publishing scipy-stubs on conda-forge in #169. So if you have some thoughts on that as well @lucascolley that could certainly help.

@lucascolley
Copy link
Contributor

The first step for getting scipy-stubs on conda-forge would be to get optype on conda-forge - I can make a PR!

@lucascolley
Copy link
Contributor

Conda packages instead of PyPI

Note that pixi does have first-class support for PyPI packages, but at that point it's basically just wrapping uv.

@jorenham
Copy link
Owner Author

The first step for getting scipy-stubs on conda-forge would be to get optype on conda-forge

Ah I see

I can make a PR!

That would help a lot!

@KotlinIsland
Copy link

KotlinIsland commented Nov 28, 2024

pyprojectx is based https://pyprojectx.github.io/config/scripts/
https://pyprojectx.github.io/recipes/#run-scripts-that-use-the-projects-packages

I use it to install uv/poetry themselves and I use it in all my projects

@KotlinIsland
Copy link

can i just ask, what is the point of conda-forge over pypi?

@lucascolley
Copy link
Contributor

you can install python (okay, I just checked and uv can do this too!) and system level packages with it, and you can install packages in other languages like C++ as well. So you can use the same workflow for e.g. a C++ project and a Python project. There are also claims that conda-forge is more stable since builds have to succeed on their pipelines before a new version is released.

https://conda.org/learn/faq/#why-should-i-use-conda-and-not-just-install-everything-with-pip says:

Pip can only install Python packages and (unlike conda) cannot account for the dependency graphs connected to each package that it installs, which can break global system dependencies and/or the user's dependency stacks. Even when using pip with a tool like virtualenv, which creates isolated Python environments, it can still inadvertently install Python packages to the wrong places.

On the other hand, conda is a powerful package and environment manager that can install much more than just Python libraries. With conda, users can install entire software stacks (while remaining assured that all dependencies are accounted for and resolved), as well as R programs and libraries, Node.js, Java programs, C++ programs and libraries, Perl programs, and more. Conda has an environment management system that allows users to have all of these installed across multiple different environments; it also enables installation of complex software stacks on a system without needing root privileges, due to it being able to do all of these software and package installations in an isolated, userspace manner.

@KotlinIsland
Copy link

oh okay, cool

Pip ... cannot account for the dependency graphs connected to each package that it installs, which can break global system dependencies and/or the user's dependency stacks. Even when using pip with a tool like virtualenv, which creates isolated Python environments, it can still inadvertently install Python packages to the wrong places.

uv supports these bare minimum features btw, pip (and actually most of python and it's ecosystem) is a joke

@jorenham
Copy link
Owner Author

jorenham commented Nov 29, 2024

it's just too bad that conda is so slow (even with mamba)

@lucascolley
Copy link
Contributor

would be interested to see whether you find pixi slow! There is also https://prefix.dev/blog/sharded_repodata which you can enable in your config (https://pixi.sh/latest/reference/pixi_configuration/#repodata-config).

at least it's not as slow as mypy :)

@KotlinIsland
Copy link

at least it's not as slow as mypy :)

one of the jokes in question, have you tried mypy's daemon?

@jorenham
Copy link
Owner Author

at least it's not as slow as mypy :)

one of the jokes in question, have you tried mypy's daemon?

yea I tried it for a little bit on numpy, but I don't remember if I actually got it to work 🤔

@miloth
Copy link

miloth commented Nov 29, 2024

Hi there! I think most, if not all, could be baked in tox, which is already used by the library for other things. That would substantially decrease the project complexity and command definition complexity. Also, it would streamline the CIs, making them simpler and easier to maintain.

In my opinion, this is a good path, because all the custom command are dev tools to test the code in different ways (unit testing, lint checks, stubtest, etc.). They all fit well in the tox purpose and usage. Once defined, any of the tasks could be run with a simple command. E.g. for linting: tox -e=lint.

As mentioned, I'll work this upcoming week on cleaning up the initial draft PR I made for uv. In particular, separating into two self-contained PRs, aiming at:

  1. One that simply moves the project to uv, keeping all the rest as is.
  2. Removing poe in favor of a tox-only configuration.

@wolph
Copy link

wolph commented Nov 29, 2024

Any thoughts on this, @wolph?

I've only done some basic tests with some of these tools so I can't say I've got too much experience with them. I've been burned by the newer/better package manager implementations many times before so I prefer to wait out these types of things until they've existed for a few years since it can be quite a chore to get them working.

Tools such as pipenv spring to mind... great in theory, in practice I found it to be too slow to be usable.
While poetry has had good performance for me, there were several killer bugs in the earlier versions that were really hard/impossible to workaround as soon as you got to more advanced usage. And I'm not sure if the groups feature is working properly these days but it didn't work at all last time I tried.

In any case... I'd suggest a few light tests with these projects before you invest too much time into them. I might follow suit for my projects too ;)

@jorenham
Copy link
Owner Author

Hi there! I think most, if not all, could be baked in tox, which is already used by the library for other things. That would substantially decrease the project complexity and command definition complexity. Also, it would streamline the CIs, making them simpler and easier to maintain.

In my opinion, this is a good path, because all the custom command are dev tools to test the code in different ways (unit testing, lint checks, stubtest, etc.). They all fit well in the tox purpose and usage. Once defined, any of the tasks could be run with a simple command. E.g. for linting: tox -e=lint.

I kinda like that actually. We could probably also alias those specific tox -e cmds with uvx if we'd wanted to 🤔.

I added to the list of contenders 👌🏻.

@jorenham
Copy link
Owner Author

Any thoughts on this, @wolph?

Tools such as pipenv spring to mind... great in theory, in practice I found it to be too slow to be usable. While poetry has had good performance for me, there were several killer bugs in the earlier versions that were really hard/impossible to workaround as soon as you got to more advanced usage. And I'm not sure if the groups feature is working properly these days but it didn't work at all last time I tried.

Most of my other (active) project are using uv now instead of poetry. At this point it can basically do everything that poetry can, as it recently added uv build, uv publish and PEP 735 dependency groups.
The uv sync stuff took me a while to get used to, but the speedup is truly impressive, especially for larger projects. So let's just say I can't imagine going back to poetry at this point.

For that reason I have been wanting to migrate scipy-stubs to uv as well (#49), but for some reason I wasn't able to get it working (which has something to do with this being a stub-only package, which either uv or hatch is lacking support for from the looks of it). But luckily @miloth managed to get uv working in #174 either way. So as far as I'm concerned, we'll also be switching to uv here in scipy-stubs.

This issue is mostly about the task runner poe, which (unlike the name suggests) can be used independently of poetry. Currently it's configured with tasks like poe format that run mdformat and ruff format, and poe stubtest which is basically a poetry run stubtest alias that includes the right config files, allowlists, cwd, etc. Its currently configured as follows:

scipy-stubs/pyproject.toml

Lines 56 to 116 in 1499c09

[tool.poe.executor]
type = "poetry"
[tool.poe.tasks]
clean = """
rm -rf
codegen/*.pyc
codegen/__pycache__
scipy-stubs/**/*.pyc
scipy-stubs/**/__pycache__
./**/.mypy_cache
./**/.ruff_cache
./**/.tox
"""
mdformat = """
mdformat
CODE_OF_CONDUCT.md
CONTRIBUTING.md
README.md
SECURITY.md
tests/README.md
"""
_ruff_format = "ruff format"
_ruff_check = "ruff check --show-fixes"
codespell = "codespell"
repo-review = "repo-review ."
format = ["mdformat", "_ruff_format"]
ruff = ["_ruff_format", "_ruff_check"]
check = ["mdformat --check", "repo-review", "codespell", "ruff"]
lint = ["check", "format"]
pre-commit = "pre-commit run --all-files"
tox = "tox -p all"
_test_bpr = "basedpyright tests"
_test_mypy = "mypy --config-file=pyproject.toml tests"
typetest = ["_test_bpr", "_test_mypy"]
[tool.poe.tasks.pyright]
cmd = "basedpyright $path"
args = [{name = "path", positional = true, multiple = true, default = "scipy-stubs codegen"}]
[tool.poe.tasks.mypy]
cmd = "mypy --config-file=pyproject.toml $path"
args = [{name = "path", positional = true, multiple = true, default = "scipy-stubs codegen"}]
[tool.poe.tasks.stubtest]
cmd = """
stubtest
--mypy-config-file=pyproject.toml
--allowlist=.mypyignore
--ignore-unused-allowlist
$modules
"""
args = [{name = "modules", positional = true, multiple = true, default = "scipy"}]
[tool.poe.tasks.codemod]
cmd = "python -m libcst.tool codemod -x --hide-progress --include-stubs codegen.mods.$name $path"
args = [
{name = "name", positional = true, multiple = false, required = true},
{name = "path", positional = true, multiple = false, default = "scipy-stubs"}
]

So that's a rather nasty mess imho, which is of the reasons we're looking for an alternative.

Anyway, that's what I meant with "task runner". In some cases is indeed part of the package manager (e.g. in case of pixi, or in case of JS there's npm and yarn). But there are also independent task runners (e.g. just, poe, tox etc), which is in our (future) uv case the only possible route (at least until uv releases its own task runner, which it probably will).

So I guess we're basically looking for a fancier bash alias that's could replace poe as a more "agnostic" alternative that can be configured with spaghetti. Mostly because remembering long commands isn't very 10x (which we clearly all are here).

@lucascolley
Copy link
Contributor

uv + tox (maybe with uvx) sounds like a good combo to me. Would probably be pretty straightforward to translate that setup to pixi in the future if any motivation arose.

@jorenham
Copy link
Owner Author

uv + tox (maybe with uvx) sounds like a good combo to me. Would probably be pretty straightforward to translate that setup to pixi in the future if any motivation arose.

Apparently there's also https://github.com/tox-dev/tox-uv, which could make things even easier 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants