alt.hn

7/21/2026 at 8:30:22 PM

Some more things about Django I've been enjoying

https://jvns.ca/blog/2026/07/21/more-nice-django-things/

by surprisetalk

7/26/2026 at 9:52:11 AM

There are so many footguns[1] in async python but it really has stolen the zeitgeist of modern python web. Synchronous django has a lot to commend it. If you deploy it reasonably well (workers, behind a caching reverse proxy etc) it's easy to operate in production even under duress.

It's not going to be the right stack for long lived websocket connections or whatever but for a CRUD-ish or enterprise app, often very productive.

[1] buffer bloat is too easy to sleep walk into

    queue = asyncio.Queue()  # oops
unbounded concurrency

    await asyncio.gather(*(fetch(item) for item in items))  # look mum! no outbound sockets left or maybe even no file descriptors
accidental blocking

    data = requests.get(url).json()  # oops! we're blocking the event loop
and sure you can setup a separate task to measure the event loop latency and alert on that but this is the kinda thing you'll never find in a tutorial, you just need to experience this stuff and figure out a solution you like

I can go on and on about async python (cancellation bugs, leaking a task - that has a cataclysmic failure mode where if you forget to hold a reference to your asyncio.create_task() then it's all weak refs in that machinery so your task can get garbage collected before it ran or completed in production! super tricky forensics. Then there's all the obvious stuff like race conditions, new ways of creating deadlocks, blah blah i really can go on for days.

by CraigJPerry

7/26/2026 at 8:28:18 PM

Please go on. I also feel like asyncio is a big hack. Even just accidentally blocking the event loop is way too easy. And I couldn't believe it when I read that you need to store a reference to a task in a set to keep it from accidentally getting canceled. How did this become the main stack of AI backends? It's like node but slower AND much easier to mess up because of synchronous IO.

by loevborg

7/26/2026 at 9:19:35 PM

I'm not sure i see it as a hack, but i do feel unduly burdened as a developer by async in python. I feel like there's a lot that i have to think about and i'd appreciate more help from the language.

I don't want to be overly critical, there's languages that people complain about and then there are languages that no one uses... If i compare it to js/ts, some stuff is genuinely better in Python - e.g. if you missed an await. While both ecosystems have lint tools available for this, but the behaviour is just friendlier in python.

Structured concurrency is better in python, but even if TaskGroup is nicer to use than AbortController, it still has its own foibles which means i'll usually advocate for AnyIO.

But the js/ts ecosystem just generally benefits from being async from the get-go where python you're just a time.sleep() away from a bug that will slip through dev envs and ci pipelines undetected and only rear its head under load in prod.

If i have a tip to share its the debug flag for asyncio run:

    asyncio.run(f(), debug=True)  # find some more issues before prod

by CraigJPerry

7/26/2026 at 8:57:40 PM

I would love a blog post on this, in case you ever considered writing one!

by codethief

7/26/2026 at 9:17:27 PM

Not to be a downer since a lot of JEvans’ content is great. People should really give .NET a try. I don’t know if we are just old greybeard curmudgeons who look at this and go “is this a new thing? haven’t we been doing this for decades?”, but .NET out of the box with a few packages for databases, logging, etc is so pleasant you don’t even think about it. Maybe it’s just not a vocal community idk.

by hecreto

7/26/2026 at 9:50:26 PM

At this point Django also qualifies as "for decades" - most (maybe all?) of what's in this post applied back when it was new. The basic design has been stable for a very long time.

by Izkata

7/26/2026 at 9:53:29 PM

To be fair, for grey beards, python predates .net and I was using Django in 2008, which predates .net mvc.

by rileymat2

7/26/2026 at 7:50:27 AM

> Some light load testing (with (ab -n 1000 -c 1) shows that right now we can serve about 2-3 requests per second (on a ~$10/month VM).

> After turning on template caching, it seems like the site can now pretty easily handle 12 requests per second or so without using all of the CPU. I have not carefully benchmarked the before and after but it seems like it’s made a pretty big difference.

That seems crazy low, I think there has to be something else going on here.

by echoangle

7/26/2026 at 8:23:43 AM

Those numbers sound... Single-threaded. Like they're using the development runserver instead of uwsgi or gunicorn.

by shakna

7/26/2026 at 9:57:06 PM

Development runserver has been multithreaded by default for over a decade. I think you need to go back to major version 1 to see it single-threaded by default. Maybe affected by the GIL though.

by Izkata

7/26/2026 at 8:30:10 AM

A $10/month VM might only have a single thread anyway. Some providers like lightsail are really slow too.

by jonatron

7/26/2026 at 8:37:36 AM

You can run multiple OS threads (gunicorn workers) on one VM thread so the workers don’t have to wait for each others request to finish though, right?

And if you pay $10/month for a single threaded machine, you’re overpaying by a lot.

by echoangle

7/26/2026 at 8:49:27 AM

True, but in this case with SQLite, there's unlikely to be much of a difference because there isn't the spare time available when waiting for a separate database server. I don't know what providers are good for a $10/month instance these days.

by jonatron

7/26/2026 at 10:09:16 AM

How are you spending any non-negligible time reading from SQLite at 12 requests per second though? That would mean you’re spending something like 50 ms per request on reading from SQLite.

by echoangle

7/26/2026 at 9:59:29 AM

Most of the time you're hitting SQLite, you're just reading from it, and so it doesn't hold anything up.

by ErroneousBosh

7/26/2026 at 9:37:37 AM

For a cheap VM, I'd still be expecting in the range of 500-1000 connections a second. Green threads are cheap, even with a single processor.

For a half-decent VM, I'd be expecting multi-thousand.

Single figures a second, is choked to a single connection at a time.

by shakna

7/26/2026 at 9:29:19 AM

Also, they may be serving static files through Django. Otherwise, it's really, really low.

by BiteCode_dev

7/26/2026 at 11:28:04 AM

That’s a number I would been disappointed with 25 years ago, running Perl CGI on a 700MHz Pentium III.

by bigfatkitten

7/26/2026 at 1:42:34 PM

Yeah... in the place I worked, for a while, they didn't have a package index for Python packages (similar to PyPI), so, I wanted to write one. At the time I had a love-hate relationship with Ada, so, after trying to do something with Python and thinking how much resources I would have to ask for and whether I'll need load balancing etc... I checked what Ada's (somewhat unfortunately named AWS...) would need to be used as that kind of index. Suffices to say that I wouldn't need any of the "reverse proxy" servers, no caching, no load-balancers... It would be fast enough to service a company with thousands of employees on a very modest h/w setup.

Using Django is like trying to walk on a highway, with a crutch. Even though it has some convenience features, it's just so impossibly slow you would have to invest a lot of engineering time and resources to mitigate that slowness.

by crabbone

7/26/2026 at 2:18:23 PM

It's because -c 1 only makes 1 request at a time, which is not representative of a real website load. This was also brought up on lobsters a few days ago https://lobste.rs/c/lctz1y

by ranger_danger

7/26/2026 at 10:20:32 PM

1000ms / 12 = 83ms per request which sounds normal

by nijave

7/26/2026 at 8:36:21 AM

I have been using Django since 0.95 and I haven't seen anything which is so flexible with amazing DSLs while also making it easy to understand the magic behind it.

For the last 10 years, even in a Golang stack or Java stack, I still use Django for models and migration. I even have generators which generate Gorm (or other framework) DAO or Java hibernate classes using Django models.

With LLMs, it becomes easier since I can now write all the model, custom querysets in Django, ask the LLM to generate Golang DAO, setters and getters... and test the query against the Django generated queries for completeness.

Atlas, sqlx, sqlc and all other ORM like things in golang cannot do migrations the way Django does.

by ranedk

7/26/2026 at 2:03:07 PM

> I still use Django for models and migration

There are dozens of us! It's a great db management toolkit. I've used it to much success many times for things like managing migrations from mysql to postgres and php to python.

My opinions:

- Django apps are an anitipattern for large internal / single purpose products due to migration overhead as FKs cross application boundaries. I will die on this hill. No team is ever disciplined enough to keep apps as boundaries for relationships and constraints. Strong contrast to the rails crowd that doesn't rely on referential integrity in the db by default where this isn't "a thing".

- Goose[0] migrations in Go are really great but you have to let go of the dsl and the idea that your ORM drives your migrations, as you explicitly called out. Laravel[1] is on par with django IMO and a delight to use when in php-land. I've not tried to repurpose it like I have with Django and sqlalchemy.

- sqlalchemy and alembic is a great toolchain outside of django that get's a bit of a bad wrap / confusion from django devs. it gives you that same ability to drive the changes from the classes / structs without having to drag around all of django. It having more verbose

[0] https://github.com/pressly/goose

[1] https://laravel.com/docs/13.x/migrations

by leetrout

7/26/2026 at 3:52:48 PM

  - Django apps are an anitipattern for large internal / single purpose products due to migration overhead as FKs cross application boundaries
Totally agree with this. Now we have thousands of unsquashable migrations that require a ton of work to fix.

by pdhborges

7/26/2026 at 6:15:41 PM

Can you share more on this? Is it better to keep all models in one app?

by trojans1290

7/26/2026 at 9:39:36 PM

Well whether it's better or worse depends on your specific situation.

What I'm facing right now is a 10 year monolith modularized with applications. Like a sibling comment already discussed these applications are not reusable application so almost all advantages of having that are moot.

Now, the consequence of having this structure is that we now have complex dependencies between the migrations of these apps i.e. cyclic dependencies, dependecy constrains that are underspecified. Thousands of migrations that now take a significant amount of CI time. We would like to squash them but it requires a lot of review and manual work and if we keep using multiple apps we are going to ave the same problem in the future.

The only meaningfull gain we had with multiple apps is that we have less migration conflicts when people create migrations concurrently.

Is that advantage worth the pain? I don't think so.

by pdhborges

7/26/2026 at 10:15:47 PM

We have a distributed monolith that's 20-30 years old, that has various systems written in python, perl, VB6, and C# (and a year ago I discovered some dead unused C++ in a forgotten repo) interacting with multiple interconnected databases. We're working on migrating all of it to python, using django models.

The key thing in a system like this, that was kind of stumbled upon by previous devs who started the python migrations, is the database should be treated as its own independent unit and managed separately from the individual applications that connect to it. For example, we've defined the django models in an independent library that the individual applications import. It also contains the configuration for routing queries to the different databases - only takes a couple of lines of boilerplate in the application's settings file.

We haven't yet switched to using django migrations and are still doing updates manually, but after some work the past couple of years it would now be an option. They would go in the common library, avoiding the pain points you've listed, and could be run from any application that needed it - django tracks the migrations that were run inside the database so they'd all see the same thing and act the same way.

For us, it has absolutely been a major benefit.

by Izkata

7/26/2026 at 8:20:56 PM

I found parts of the Django RAPID architecture [0] to speak to me. It specifically advocates for just one app. Here's a part of the justification.

> Slicing up your project into apps is something that must be done early, often at the very start of development. This is a simple result of the fact that you need somewhere to put the code you're writing as you go along. In the early days and weeks of work on a new codebase, manage.py startapp gets used a lot, as the high-level structure of the project starts to take shape.

> The issue here is that at this early stage, you often don't really know enough about what the project's final form will look like to correctly draw the boundaries around the apps. Functionality that feels separate at first often becomes deeply entangled, and features that sound similar end up sharing little. Over time, the key concepts and models in your system become clear, and if these are colocated with unrelated or irrelevant code, the waters of the project become muddy and maintenance becomes difficult - before the project is even in production!

> While it is technically possible to migrate models between apps, Django doesn't make it easy, particularly if the models in question have foreign key or many-to-many relationships with other models. And if you think about it, it's not really a technical limitation of the sort that could easily be solved with a PR into Django. It's a conceptual problem: if migrations are a historical record of changes to models, and migrations are encapsulated in the same app as those models, then moving a model to a different app necessarily creates a historical coupling between the two apps that shouldn't really exist.

[0] https://www.django-rapid-architecture.org/structure/

by dotandgtfo

7/26/2026 at 9:08:57 PM

Not the author, but I no not understand the desire to use multiple apps. I am never going to want to carve one out as a separate module I re-use in another product. It is all interconnected, why add arbitrary boundaries separating them? Put everything into a "core" app and move on with life. Maybe if you are an enormous organization working on Instagram where you have rigid responsibilities per team.

by 3eb7988a1663

7/26/2026 at 9:22:29 PM

So you’d prefer one file with all models? Do you break out into apps for business logic? Keep models in one app/file. Then domain driven design elsewhere?

by trojans1290

7/26/2026 at 9:31:56 PM

As things get more complicated, I will separate out by some kind of concept. Which can be something as simple as:

  /coreapp
    /forms_foo.py
    /forms_bar.py
    /models_bar.py
    /models_foo.py
    /views_bar.py
    /views_foo.py
You can do a more sophisticated module layout, but essentially something as straightforward as the above, all under a single "core" application. Prevents Django from fighting you when you want to work across the arbitrary "app" boundary.

by 3eb7988a1663

7/26/2026 at 9:26:59 PM

You don't have to put all your modules into a single file. You can break them into multiple files and the import them into a model file just so that Django loads it from the expected location.

Instead of apps you can just split your components inside a single app using regular python modules.

by pdhborges

7/26/2026 at 11:14:02 AM

I've never done it, but now that you say it, it makes a lot of sense. Using Django just to manage the database and do migrations, even behind other language stacks.

You also get the Django admin interface for free.

I once tried using SqlAlchemy but I couldn't help asking myself why it felt so complicated compared to Django.

by 0xpgm

7/26/2026 at 8:24:28 PM

Running your API in Rust/Go/etc and then doing the admin and migrations via Django is a hidden superpower. I’ve said this on HN in the past few years.

by Klonoar

7/26/2026 at 11:22:50 AM

People who hate ORMs have just never tried Django :D

by ranedk

7/26/2026 at 2:03:30 PM

Or Laravel's Eloquent

by stef25

7/26/2026 at 7:20:47 AM

Good ole Django. Worked with a number of frameworks (tm), but nothing really quite scratches my itch like Django does. I still find the ORM and database migration system unmatched.

by altbdoor

7/26/2026 at 8:20:11 AM

I found Django a bit hard to get on with vs. other frameworks and I've used Rails, .NET MVC and Express (and friends). I just found more friction trying to achieve X for any given X for some reason. Not sure why.

by hahahaa

7/26/2026 at 2:46:07 PM

That's the whole beauty of frameworks and languages. Some of them just "click" with you. At the end of the day we can all build what we need.

by mcrk

7/26/2026 at 8:44:36 PM

> the site can now pretty easily handle 12 requests per second.

Right prod architecture (nginx -> gunicorn -> django, with nginx serving static assets), decent PRAGMAs for sqlite3 and caching for generic content should improve the RPS one or two orders of magnitude.

by lazyant

7/26/2026 at 12:41:36 PM

For Django's default template language, does it still have these limitations?

1. Brackets aren't allowed to help with boolean expressions like {% if a and (b or c) %}

2. You can't do basic arithmetic like {{ x * 2 }}, but you're allowed to do {{ x | add:"2" }}. There's hacks to multiply using {% widthratio a 1 b %} or division with {% widthratio a b 1 %} though (https://stackoverflow.com/questions/18350630/multiplication-...).

3. You can't assign expressions to variables like {% with x = a or b %}, so you have to repeat yourself.

4. You can't capture HTML generated from template code in a variable to pass into a partial template to write slots-style HTML components e.g. {% capture x %}Hello {{ username }}{% endcapture %}{{ include "partials/header.html" with body_html=x }}.

5. You can't pass variables to model methods.

I understand there's a philosophy that templates shouldn't contain complex logic, but I find the above pretty arbitrary and leads to code that's harder to maintain. Addition is okay but not multiplication? Boolean logic is okay but not with brackets? I often have to puzzle out some way to get my code to work that goes against what I'd normally want to do, some I'm forced to duplicate template code because you can't put expressions in variables or move basic one-off logic into views (which has poor locality https://htmx.org/essays/locality-of-behaviour/ and makes it harder to move template snippets between pages).

It's like hiding the kitchen knives because they might be misused.

Is Jinja2 a practical alternative or there's friction to using it?

by seanwilson

7/26/2026 at 1:48:57 PM

> Is Jinja2 a practical alternative or there's friction to using it?

jinja2 is drop in by changing the template backend. You can actually run both at the same time (just can't mix them, ofc).

https://docs.djangoproject.com/en/6.0/topics/templates/

by leetrout

7/26/2026 at 2:39:42 PM

It's a practical alternative, but definitely not a drop-in replacement! I've been working on migrating a django project to jinja2 lately, see the diff: https://framagit.org/la-chariotte/la-chariotte/-/merge_reque...

A few notables differences:

- many controls are now functions/variables (that's good!), and some change name, for example `{% csrf_token %}` -> `{{ csrf_input }}`

- calling methods without parenthesis does not work (that's good!), for example `query.all` -> `query.all()`

- in tests` response.context` is replaced by `response.context_data`, which is not set when calling `render` directly (need to return a proper `TemplateResponse`)

- template folders need to be renamed from `templates` to `jinja2`; there may be a way to change this behavior, but i did not find it, and this change is written so small in the docs i lost an entire day over it

by selfhoster1312

7/26/2026 at 2:57:25 PM

The migration is fairly simple and well documented.

The problem may be the lack of jinja support for 3rd party django apps (mostly legacy). So make sure they support it first.

by mcrk

7/26/2026 at 8:34:01 AM

I mostly use Go + SQLite for all the things I used to use Rails, JavaScript, or Python for.

I find python django wastes too much resources, just look at memory usage.

One of my web app backend (go) is serving approx 100 req/s right now and i look at pprof i see it's not bottlenecked by CPU but mostly IO and i love this.

Writing concurrent code in Go is easy, the code i wrote 10yrs ago still compiles with no issue! This is why i am never gonna switch.

My go apps use very little memory, so we can scale to many users for very cheap.

For larger apps i use postgres (why? replication is easy using pgfailover, high demand apps need multiple api servers so it's out of process db like postgres is fine) but most of my web app use HTMX and if we need some reactivity, i use react (simply due to react experience from work)

For our maintenance calorie tracking app, which is free and has no ads, we have to use as few resources as possible as we scale to thousands of users: macrocodex (which figures out maintenance calories from weight and calorie intake). We initially used Haskell.

Later, it became slow and cumbersome to develop in (developing on an Apple Silicon Mac and deploying to x64 is a pain), even though I liked writing Haskell code. I even tried nix and wasted a day on that! I had a choice between OCaml and Rust. I picked Rust and never looked back.

The algorithm serves in 0.1 ms on Rust. In Haskell, it was 0.2 ms, and memory usage was twice that of Rust. There are many optimization possible in Rust which i didn't do (for sake of simplicity) yet i received good performance.

Yeah, I use Docker to compile Rust, but it's pretty fast, much faster than what I had with Haskell, so the developer experience is great.

By switching to Rust, the LOC dropped to half of what we had in Haskell.

project turned out to be successful. It has already produced guaranteed weight loss or weight gain for many people.

So I set out to create an algorithmic workout app, for which I am using Rust and Go. The mobile app is in Flutter.

by faangguyindia

7/26/2026 at 9:24:47 AM

Appart from the fact that you find that Python wastes too much memory, what is your point ? I think that any person choosing Django knows that Python by nature will not be the most efficient language. Apart from that Django is battle-tested and can help bring a stable "product" quite quickly.

by nargek

7/26/2026 at 9:38:22 AM

if "2-3 requests per second" per author is what you wanna do on $10 server go ahead". My server does 100 RPS on $16 instance

neither you are saving any time, nor money.

>part from that Django is battle-tested and can help bring a stable "product" quite quickly.

this is a myth, you'll not save anytime. Only way you can save time is if you've experience in this but same is true if you write your app from scratch in Go from your learned patterns.

by faangguyindia

7/26/2026 at 10:44:30 AM

> if "2-3 requests per second" per author is what you wanna do on $10 server go ahead

That's not a Django limit and there's something going on with the authors setup. 100 RPS on a $16 instance would be easily doable with Django too.

> neither you are saving any time, nor money.

How do you know? I'm pretty sure I can set up the same webapp in Django much faster than in go, so I'm saving both.

> this is a myth, you'll not save anytime. Only way you can save time is if you've experience in this but same is true if you write your app from scratch in Go from your learned patterns.

Why do you think all the built in stuff in Django does not save time? Any argument for that?

by echoangle

7/26/2026 at 9:42:08 AM

> as a meta comment: I’ve been working on talking about my programming opinions by just saying “THING does not feel good to me, I prefer OTHER THING instead”. That post I linked to says that function-based views are the “right way”. I’m not very invested in whether it’s “right”, but it’s validating to know that other people feel similarly to me about inheritance

I admire this about Julia a lot. Her texts and zines are exploring software in a way that encourages curiosity rather than promoting a singular point of view.

by sakjur

7/26/2026 at 12:19:51 PM

Do not use the development http server in a production setting. Use gunicorn or some equivalent.

I had the same issue with incredibly low throughput on beefy machines and it's because the dev server implementation is single threaded and does not do concurrency at all.

Switch to gunicorn.

by imperio59

7/26/2026 at 1:31:25 PM

Better yet, put gunicorn behind nginx, make sure all static assets are served by nginx, add appropriate Cache Control headers. Furthermore understand and use Django’s page caching.

by gnz11

7/26/2026 at 12:00:28 PM

Holy 2003 that website

by rubyfruit

7/26/2026 at 8:26:41 AM

The Django filter syntax with the double underscores is like fingernails on a chalkboard to me. I find it insane that they didn't just use operator overloading to create a real query expression language.

by BrenBarn

7/26/2026 at 9:09:35 PM

I think you can do that with querysets, Q, and F. The kwargs are a limited convenience.

by mixmastamyk

7/26/2026 at 9:03:03 AM

Or now that python has ~types, this is really an area where things could be improved. Filtering would just be lambda predicate with fields auto complete as seen in .NET, scala, etc

by ezst

7/26/2026 at 10:10:54 AM

There may be many reason other than rejecting that suggestion leading to what it is know. Your statement somehow suggests that it was deliberately decided against what you propose. I don't think we know that.

I can't quite picture how operator overloading would look like, could you give an example?

by 7bit

7/26/2026 at 10:51:20 AM

> I can't quite picture how operator overloading would look like, could you give an example?

Instead of this:

self.filter(end__gt=self._midnight(today))

You could write a "Field" class that implements __getattr__ and __gt__ so you could do

self.filter(Field.end > self._midnight(today))

The "Field.end > self._midnight(today)" would evaluate to an object that would just store "my field name is end and my value needs to be larger than xyz".

filter() can then look into its argument list and construct the filter criteria from the passed Field objects instead of the key value pairs as it does now.

by echoangle

7/26/2026 at 11:12:07 AM

if self._midnight(today) returns a datetime object, than:

   self.filter(end__gt=self._midnight(today))
will evaluate to:

   self.filter(end__gt=<some_datetime_object>)

While

    self.filter(Field.end > self._midnight(today))
will evaluate to:

   self.filter(<True/False>)

by pbalau

7/26/2026 at 11:35:19 AM

Not if you do the magic with getattr and comparison overrides. You actually need to do it on the metaclass because the Field as I wrote it isn't an instance but this works:

    from datetime import datetime

    class Filter():
        def __init__(self, name):
            self.name = name
        def __gt__(self, value):
            return {
                "field": self.name,
                "operator": ">",
                "value": value
            }

    class FieldMeta(type):
        def __getattr__(cls, name):
            return Filter(name)

    class Field(metaclass=FieldMeta):
        pass

    print(Field.end > datetime(2024, 1, 1))
This gives:

    {'field': 'end', 'operator': '>', 'value': datetime.datetime(2024, 1, 1, 0, 0)}
You can make python return arbitrary values for comparisons by overriding __gt__ (and lt, eq) on the first operand (which we control here since it is a Field class), it doesn't have to be a bool.

Edit:

You can even make a little adapter to use this with the current filter system if you really want to:

    from datetime import datetime

    class Filter():
        def __init__(self, name):
            self.name = name
        def __gt__(self, value):
            return {
                "field": self.name,
                "operator": "gt",
                "value": value
            }
        
        def __lt__(self, value):
            return {
                "field": self.name,
                "operator": "lt",
                "value": value
            }
        
        def __eq__(self, value):
            return {
                "field": self.name,
                "operator": "eq",
                "value": value
            }

    class FieldMeta(type):
        def __getattr__(cls, name):
            return Filter(name)

    class Field(metaclass=FieldMeta):
        pass

    def _(*args):
        kwargs = {}
        for arg in args:
            k = arg["field"] + "__" + arg["operator"]
            kwargs[k] = arg["value"]
        return kwargs

    def filter(**kwargs):
        for k, v in kwargs.items():
            print(f"{k} = {v}")

    filter(**_(Field.end > datetime(2024, 1, 1)))
This prints

end__gt = 2024-01-01 00:00:00

by echoangle

7/26/2026 at 12:17:00 PM

If you change an operation that is meant to return a Boolean to return anything else, you are insta fired.

by pbalau

7/26/2026 at 10:23:04 PM

That's a well established pattern in Python, for instance with Numpy.

by BrenBarn

7/26/2026 at 1:41:33 PM

I would have agreed with this, and then they did the `pathlib.Path` bit of cuteness with the `/` operator: https://github.com/python/cpython/blob/5afbb60e0283caaf34990...

And despite my misgivings, it’s really ergonomic.

by vtbassmatt

7/26/2026 at 2:46:12 PM

If you divide a Path by another Path, you get a Path. If you compare two Paths, you get a Boolean. It is not really the same.

by pbalau

7/26/2026 at 12:28:33 PM

You mean like the numpy authors that let the comparison operators return arrays?

Also, apparently SQLAlchemy does exactly what I proposed so apparently they are erring in their ways too.

I honestly don’t find it that bad.

by echoangle

7/26/2026 at 11:59:00 AM

How would you model string comparisons with LIKE?

by 7bit