Ask HN: High quality Python scripts or small libraries to learn from
I found that reading other people's code is very beneficial for my own coding. But I haven't found a resource that lists some great code in Python which is not a giant codebase. Any suggestions?
61 comments
[ 3.8 ms ] story [ 64.3 ms ] threadThis one came in handy not too long ago: https://github.com/openai/openai-cookbook/blob/main/examples...
take the fn starting at line 387. they comment why they do certain imports, but this function is comparatively underdocumented. it's not easy to wrap my head around the control flow. some bits are nested about 6 levels too deep for comfort, there are too many positions from which it can return or raise, and the function is about 3x too long
really difficult to grok what is happening here.
https://docs.astral.sh/ruff/
I just installed and enabled all the rules by setting select = [ "ALL" ]
And then looked at the 'errors' it showed me for my existing code base and then excluded some rules which don't interest me.
I also have it set up in my IDE, so it'll show me the linting errors while coding.
In a larger code base there will definitely be many 'errors', but using it cleaned up my code really good and it stopped me from some footguns.
Single letter variable names are totally fine in some cases. And while very long functions may be bad, it's pretty annoying when you're adding one line to a function for the linter to say "nope. have you considered dropping everything and refactoring this?"
You can easily turn them off though. I can't remember any code based ones that are really wrong.
Maybe some are prone to false positives, e.g. warning about a default `= []` argument. But you can waive them individually.
Without a very good grasp of the language, it can be counterproductive to deep learning. The linters teach what to do, but not why, so it’s hard to grasp how the codebase is worse without following the linter, or when it’s appropriate to disable a linter vs dealing with it.
Ie I’m not a great JS dev. When the linter says “this should be an arrow function” I understand how to do that, but not why an arrow function is preferable there or in general. I would probably be a better JS dev if I hadn’t had the linter, felt whatever pain from not using arrow functions, and know why they’re important. Or never feel the pain and realize it’s a style choice more than a functional one.
I prefer using them to help me remember things I already understand. I know why mutating a copy of a string doesn’t mutate the caller’s copy, so I’m happy to have a linter point out when I’m trying to do that inadvertently.
I'm on the same boat. I started using python ~1 year ago, because it is the main language I use at my dayjob. And I didn't really use python before this (although I was already proficient in other languages).
In the beginning my code was very messy and I spent much time searching for how to do things the 'correct' way.
And ruff made this so much easier, and it made me look at some python topics more thoroughly. And now I'd say I have a very good understanding of python and its best practices, and I'm now one of the most proficient python developers in my department (it's not a high bar, we have many data scientists, which are most of the time only proficient in their libraries/tooling they use, and I'm one of the few that is not a data scientist).
I'm not saying that solely ruff was the reason I'm now in proficient in python, but it made it easier + I would have never looked into some things without it.
For example, I also type my python code, and before I used ruff I had many problems with circular dependencies. But ruff could fix it with a simple automatic fix by using from __future__ import annotations and if TYPE_CHECKING.
And the ruff documentation also gives more explanation on the why and how for most of their rules, which is also very valuable.
https://docs.astral.sh/ruff/rules/future-rewritable-type-ann...
https://docs.astral.sh/ruff/settings/#lint_flake8-type-check...
Ruff specifically actually has a web page for every single check with a section on the rationale behind it.
I regularly use this when I see an error that I don't understand the purpose of, and am often convinced, though sometimes I recognize that the thing it's trying to protect me from doesn't apply in my particular case and so I disable it. Regardless. I feel it has had the effect of making me a better developer.
I've come to rely on that so much, it's really annoying when the error is from mypy, whose tooltips do not have such links.
Patiently waiting for Astral's mypy-killer!
If you don't know how to use the tools, you're missing out on time savings and error prevention, and once you write code that the linter doesn't like, you can't make it compatible without significant manual work.
I almost think Python would be better with mandatory types....
https://github.com/simonw/datasette https://github.com/simonw/sqlite-utils
So, his code might not be a good place to find best patterns (for ex, I don't think they are fully typed), but his repos are very pragmatic, and his development process is super insightful (well documented PRs for personal repos!). Best part, he blogs about every non-trivial update, so you get all the context!
I agree with others that code formatters like black or ruff might be helpful to you. The literature surrounding them, such as PEPs concerning code formatting, often include examples you may find useful.
[0] https://click.palletsprojects.com/en/8.1.x/
Avoid anything developed/maintained by one corporation. In general, their organizational hierarchy leads to bad patterns and resists useful changes that don't conform to the goals and patterns of the business or engineering leads. Grassroots OSS projects aren't always better, but they're less likely to have a monoculture and perverse incentives.
There are some exceptions... I'd say the `statistics` module is one [1], the `collections` module might be another [2]. But in general, it's probably not the best place to start.
If you stumble upon the `multiprocessing` library source code as inspiration for "good Python code"... you're going to be in for a bad time and your future collaborators will not be happy.
[1]: https://github.com/python/cpython/blob/3.12/Lib/statistics.p...
[2]: https://github.com/python/cpython/blob/3.12/Lib/collections/...
It is an improvement for the the tiny but efficient web2py web framework.
https://github.com/amontalenti/elements-of-python-style#some...
The style guide itself, published a few years back, also has some suggestions with small code snippets.
The entire point is not to just mindlessly consume a code base, but instead form an idea of how to approach the problem and then see if your hypothesis is correct. Then comparing your approach to the actual approach.
This can show you things that you might've missed taking into account.
For example, gallery-dl's incidental complexity all lies in centralizing persistent state, logging, and IO through the CLI. It doesn't have sufficient abstraction to allow it to be rewired to different UIs without relying on internal APIs that have no guarantee that won't change.
Meanwhile a similar application in yt-dlp has that abstraction and works better, but has similar complexity in the configuration side of things.
Edit: speling
It's almost archaeological.
Not exactly small, but great.
On that subject, Raymond Hettinger has a great talk called “Beyond Pep8” that talks about how to de-java your codebase among other things. Also reading the book Fluent Python now and it is so far excellent.
https://www.dabeaz.com/tutorials.html
https://youtube.com/@dabeazllc
I also like Raymond Hettinger.
Here's an excerpt from the readme: "Beyond Jupyter is a collection of self-study materials on software design, with a specific focus on machine learning applications, which demonstrates how sound software design can accelerate both development and experimentation."
Grind this out painstakingly and then copy and paste that as boilerplate for the rest of your natural life.
Flask, in particular, has a very small number of open issues (2) for a project that is pretty popular. Its also maintained by a competent team and has a lot of project best practices.
https://github.com/pallets/flask
https://github.com/pallets
https://pypistats.org/packages/flask
https://pypistats.org/packages/django (for comparison)
It's relatively small and I think the main take away would be the use of Protocols for the pluggable backend system. I hope you get something out of it :)
https://github.com/Llandy3d/pytheus