[project.scripts] is the PEP621 equivalent, supported by multiple backends including vanilla Setuptools. (When you use [tool.poetry.scripts], it's really the build backend, Masonry, that cares.) So that's the uv way, too. Or the "bear skins and stone knives" way.
I don't know what you mean by "without being a package". I guess you mean that Poetry will also run your code without installing it anywhere, and use the marked entry points directly. Per the other replies, apparently uv will get an equivalent soon. But really, the point of having `pyproject.toml` in the first place is to explain how to build an installable wheel and/or sdist for your project, and you basically get it for free. (Even if you don't include a [build-system] table, the standards say to use Setuptools by default anyway.)
(Of course, uv can already `run` your entry point, but this involves installing the code in a temporary venv.)
> without some pretty major refactoring of my internal structure and import declarations. Maybe I've accidentally cornered myself in a terrible and ill-advised structure?
Possibly. Is the code up on GitHub? I could take a look.
>By "without it being a package", I mean that I don't have `src/foo`, which has `src/foo/__main__.py`, but e.g. `src/main.py`.
This doesn't matter. What does matter, though, is that [project.scripts] doesn't support passing arguments - the entry point is only specified as path.to.module:function , which is expected not to take any arguments (although of course it can read `sys.argv`, which will be forwarded from the wrapper). (You can, however, specify any callable, not just a function; and it could be a nested attribute of some other object.)
As far as I'm aware, there's no formal name for this syntax, and only indirect documentation of what's supported - via Setuptools, which originated it:
You could fix this by just making functions that hard-code the name (or e.g. use `functools.partial` to get what you want). With that properly set up, any standards-compliant build backend will put the needed metadata into your wheel, and Pip and uv will both read that metadata and create the necessary wrapper when installing. (This is "recommended" behaviour for installers in the wheel standard, but not required IIRC.)
Then for example, on Linux, you end up with a wrapper script in the environment's bin folder, which looks like:
#!/path/to/.venv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from main import run_botch_bot
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(run_botch_bot())
(On Windows, IIRC you get cookie-cutter compiled executables that read their own filename and use it to do the right thing, perhaps with a Python shim to do the import or something.)
Thanks for the links. This helped point me in the right direction. I made no-argument callables in my launch script and ran `uvx migrate-to-uv`. I then changed the [tool.hatch...] section to this:
Glad it worked. Most build systems attempt automatic package discovery, but they might not assume that you want to include top-level modules. I haven't tried Hatch(ling) so I can't advise. The maintainer posts here (and is active on discuss.python.org), though.
I don't know what you mean by "without being a package". I guess you mean that Poetry will also run your code without installing it anywhere, and use the marked entry points directly. Per the other replies, apparently uv will get an equivalent soon. But really, the point of having `pyproject.toml` in the first place is to explain how to build an installable wheel and/or sdist for your project, and you basically get it for free. (Even if you don't include a [build-system] table, the standards say to use Setuptools by default anyway.)
(Of course, uv can already `run` your entry point, but this involves installing the code in a temporary venv.)
> without some pretty major refactoring of my internal structure and import declarations. Maybe I've accidentally cornered myself in a terrible and ill-advised structure?
Possibly. Is the code up on GitHub? I could take a look.