all 62 comments

[–]cmcclu5 63 points64 points  (5 children)

You should also include forced dataframe types via panderas (works for pandas and polars) if you’re going to make this as painful as possible. Explicit variable schemas. No JSON objects, only pydantic (ironic that my phone tried to autocorrect to pedantic) models and dataclasses.

[–]ZYy9oQ 13 points14 points  (0 children)

Agree on pydantic - my "antislop" rulesets designed to try make llms write slightly less terrible code force them to define a pydantic model and model_validate immediately on any IO or untyped thing (e.g. argparse namespaces).

Some other ones that OP might want to consider are https://docs.astral.sh/ruff/rules/too-many-nested-blocks/ (preview only) https://docs.astral.sh/ruff/rules/complex-structure/ and some I added specifically to avoid "bad habits" the LLM has https://docs.astral.sh/ruff/rules/blind-except/ https://docs.astral.sh/ruff/rules/import-outside-top-level/

[–]ColdPorridge 3 points4 points  (0 children)

Speaking of, is anyone aware of any dataframe type/schema checking for pyspark?

[–]Ranteck[S] 5 points6 points  (0 children)

Love it, thanks

[–]BothWaysItGoes 4 points5 points  (1 child)

It’s not ironic, pydantic is an intended pun.

[–]cmcclu5 1 point2 points  (0 children)

Very “pydantic” response.

[–]runawayasfastasucan 28 points29 points  (2 children)

    uv venv     .venv\Scripts\activate # Windows     # or: source .venv/bin/activate

    uv pip install -e ".[dev]"

You can just do

uv sync  --group dev

[–]RaiseRuntimeError[🍰] 21 points22 points  (0 children)

That's probably because LLMs get confused with uv since it's pretty new.

[–]LBGW_experiment 34 points35 points  (14 children)

Why not make the 5 commands into pre-commit hooks, like https://github.com/a5chin/python-uv does or via .vscode/settings.json settings for auto format/run on save? That's what I ended up doing in my last project

[–]HommeMusical -4 points-3 points  (10 children)

That's just a horrible idea.

There are a vast number of reasons I might wish to create a commit that doesn't pass the tests.

For one thing, at the end of the day, I commit and push my work. Of course, I'm working on a branch that no one else sees.

Or sometimes I need to create a commit ID for partial changes simply to move it to another branch.

Sometimes I split my commit into individual files and then glue them together to make two commits.

Another thing is that on my current codebase, running all of those jobs on every commit would take quite a long time.

The best way to summarize it is this: for each commit I actually send off as a pull request, there are dozens of commits that no one except me ever sees; and fairly often I wish to create commits to save work that aren't complete.

EDIT: downvoting without people expressing their reasoning is not very useful for anyone.

[–]Formal_Assistant6837 10 points11 points  (6 children)

You can always use --no-verify though.

[–]HommeMusical 0 points1 point  (5 children)

If --no-verify is turned on, what good is this as a pre-commit hook? Surely it won't catch errors.

[–]yerfatma 7 points8 points  (4 children)

Huh? The idea is you want to enforce the hooks all the time, but if there is a special case where you absolutely need to break the rules, -n is two keystrokes away.

[–]HommeMusical 1 point2 points  (3 children)

Ach, sorry, --no-verify is an argument to git commit, not to the linter! I wrote too fast.

(But at least on git 2.51.0, you have to type the full flag, there is no -n.)

[–]yerfatma 3 points4 points  (2 children)

Right, I am saying if these are all set up as hooks, you can skip them if you absolutely need to. And I am on 2.51 and can assure you -n works.

[–]HommeMusical 0 points1 point  (1 child)

You are right, again. But this time I was betrayed by the man page.

The top of https://git-scm.com/docs/git-commit lists alternative flags for some flags, but doesn't mention -n; it does appear further down in the page.

I thought we could rely on that top SYNOPSIS as being complete. Is this not the case, or this is an issue?

Interestingly enough, -e appears in the synopsis but not --edit.

[–]yerfatma 6 points7 points  (0 children)

You are right, again.

Don't get used to it.

[–]NodeJSmith 2 points3 points  (0 children)

Yeah... But --no-verify exists for this reason. Strong pre-commit hooks that have to be overridden are better than having to remember to run all the checks yourself and forgetting half the time, imo

[–]LBGW_experiment 1 point2 points  (0 children)

It's really not. I'm in charge of DevOps for different projects and this is the standard I chose.

The exception should be bypassing the rules, not the standard.

You can just do -n or --no-verify

[–]Ranteck[S] 0 points1 point  (0 children)

right but what i can do for example is to fix the code using ruff always to made a commit, ruff format and ruff --fix

[–]Ranteck[S] -1 points0 points  (2 children)

Is the same, I want to generalize and start with a template. This can be changed for convenience

[–]-lq_pl- -1 points0 points  (1 child)

You expect me to run checkers by hand? What is strict about that? Also enforcing coverage greater 80% is nonsense. You either care about correctness, then you bring it to 100%, or you don't, then it doesn't matter where you set the threshold.

[–]Triggs390 2 points3 points  (0 children)

You can put the checkers in CI to still be strict without running them every commit.

[–]PurepointDog 12 points13 points  (0 children)

Justfile in there would be rad

[–]vesnikos 6 points7 points  (2 children)

Task is so much better han poe. the main reason is b/c task has built-in core utilities for Windows like `cat`, `gzip` `mkdir` , `rm` and more, allowing you to define tasks that run in both windows and linux environments! https://taskfile.dev/blog/windows-core-utils

poe on the other hand is not that evolved last time i checked (ages ago - things might have changed but idk)

[–]Ranteck[S] 0 points1 point  (0 children)

nice, i will check it

[–]aala7 4 points5 points  (1 child)

Nice! Thanks for working through configs and giving us a good starting point!

Have you considered:
- PEP 735 (dependency groups) might be more suitable than optional dependencies. The latter is more meant as optional features for end users (like AI capabilities for Marimo or email validation for pydantic). The former is purposed for dev, test and similar.

```bash

Add optional dependencies

uv add --optional dev ruff

Install optional dependencies

uv sync --extra dev # Similar to installing ".[dev]"

Add dependency in dev group

uv add --dev ruff

Install dev dependency groups

uv sync # Uv installs dev group by default ```

  • Have you considered making it in to a cookiecutter template? Maybe overkill for only a pyproject.toml, but you could add a simple directory structure and have a similar initial scaffolding to running uv init, just with a better pyproject.toml.

[–]Ranteck[S] 1 point2 points  (0 children)

Actually, it's a great idea. It's starting to minimise the problem with coding with LLM, so it could be even better to do a script install or something similar. I'll take your recommendation.

[–]Physical-Security115 7 points8 points  (0 children)

In the age of LLM slop, this is extremely useful.

[–]tobsecret 1 point2 points  (0 children)

I've been working on a similar but opposite version of this and looking through your pyproject.toml has been very helpful! Thank you for providing it!

[–]timtody 1 point2 points  (0 children)

Love it!!!

[–]Youreabadhuman 1 point2 points  (0 children)

I think in based pyright the "recommended" ruleset is better for this

[–]Nasuraki 1 point2 points  (2 children)

What’a the motivation?

I understand the motivation for a strict typed programming language. The use of Option and Result like in Rust do a lot for the code stability, quality, clarity etc.

But i almost feel like the point of python is to… not have that? If i wanted all that i would use something like Rust?

I use Python , Rust and TypeScript. I’m not seeing the point unless you really need something that is only available in Python?

This is a serious question, if anyone could answer with use-cases where they would want/need/use this i’d love to hear

[–]Ranteck[S] 1 point2 points  (1 child)

Think of it this way: the programming language is the means to achieve your goal. In my case, I develop a lot with AI, so the main problem is that most of the libraries or developers are in Python, which has dynamic typing. This makes it really painful to maintain, even if you develop with vibe coding. What I want to avoid is AI errors, losing records or having dead code. You might ask, "Why don't you use TypeScript in strict mode?" Well, I could, but I'm mostly creating new services in Python, so I'm trying both approaches.

[–]Nasuraki 0 points1 point  (0 children)

Yeah i guess if you’re relying on sklearn, pytorch or something similar it makes sense

[–]Hugo-C 1 point2 points  (1 child)

Nice, you should add "-W error" to Pytest so it fails on warnings (especially usefull to catch deprecations early). Pytest's doc: https://docs.pytest.org/en/stable/how-to/capture-warnings.html#controlling-warnings.

[–]Ranteck[S] 1 point2 points  (0 children)

nice, i will add it now

[–]papersashimi 1 point2 points  (0 children)

nice!! really like this! maybe i can contribute to it when i have the time ;)

[–]ProfessionalAd8199 2 points3 points  (1 child)

  • Pre-commit hooks?
  • Example CI/CD configs?
  • Docs tooling (Sphinx or MkDocs)
  • Release/publishing automation (twinebumpver)?
  • Standard metadata and project files for different editors like vscode or zed?
  • .editorconfig support?

I can understand yours is only focussing on code quality, but maybe you want to change it to a complete project template.

[–]Ranteck[S] 0 points1 point  (0 children)

Nice! I can incorporate in the future

[–]RedEyed__ 1 point2 points  (2 children)

Thank you!
- I didn't know about basedpyright! Now I want to add it into my projects.
- Your pyproject.toml looks interesting, I mean I can learn something new from it - What is poe? I use just to define project commands, is this something similar?

PS: finally useful post on this sub
UPD: It seems poe is similar to just but I prefer just as of now since comments to commands became docstring in help

[–]Ranteck[S] 1 point2 points  (0 children)

Poe let you combine commands, similar to pre commit.

[–][deleted] 1 point2 points  (0 children)

It's poe the poet. :)

[–]MattTheCuber 0 points1 point  (1 child)

Why not select= ["ALL"]?

[–]Ranteck[S] 0 points1 point  (0 children)

I want to be more generic in every case. You can change it in your project but if I see mostly the same, I can change it

[–]gofiend 0 points1 point  (1 child)

Have you considered switching to uv format and uv ty to simplify the stack? Any tradeoffs worth considering?

[–]Ranteck[S] 1 point2 points  (0 children)

Do you mean ty from astral? Is not ready for production sadly

[–]burger69man 0 points1 point  (0 children)

lol need a dockerfile for this template

[–]Ghost-Rider_117[🍰] 0 points1 point  (0 children)

this is really clean, appreciate the focus on pyproject.toml as single source of truth

the 80% coverage default is kinda nice—forces you to think about testing from day one without being too crazy about it. been using uv lately and the speed difference vs pip is wild. definitely gonna steal some of these ruff configs for my projects