> "[GPT-5] can write an entire computer program from scratch, to help you with whatever you'd like. And we think this idea of software on demand is going to be one of the defining characteristics of the GPT-5 era."
3,216 karma · joined January 2, 2009
https://davepeck.org/about/
> "[GPT-5] can write an entire computer program from scratch, to help you with whatever you'd like. And we think this idea of software on demand is going to be one of the defining characteristics of the GPT-5 era."
Litestar of course supports old-school server-template-rendered sites, too; it even has a plugin for HTMX requests and responses. In practice, I find that the patterns that serve API endpoints so well sometimes get in the way of old-school "validate form and redirect, or re-render with errors" endpoints. In particular, Litestar has no "true" form support of its own; validation is really intended to flag inbound schema mismatch on API calls, not flag multiple individual error fields. Using `@post("/route", exception_handlers={...})` is pretty awkward for these endpoints. I'd be excited to see some better tools/DX in-the-box here.
Yes, I agree. “What works” is type dependent and Python’s builtin types don’t always behave the same way.
I know you know this, but for those who may not have run across it before and are curious:
f-strings invoke the format() builtin on the evaluated value.
In the case of None:
>>> format(None) # as in f"{None}"
'None'
>>> format(None, '<10') # as in f"{None:<10}"
TypeError: unsupported format string passed to NoneType.__format__
Under the hood, format() turns around and calls type(value).__format__(format_spec). Looking at the docstrings: >>> help(type(None).__format__)
Help on built-in function __format__:
__format__(self, format_spec, /)
Default object formatter.
Return str(self) if format_spec is empty. Raise Type Error otherwise.
That is, NoneType inherits Python's default object formatter, which doesn't support any format spec; if it's not empty, it's a TypeError.On the other hand, `str` and `int` both have deep custom __format__ implementations that can do much more, like padding [0].
PS: upcoming t-strings in 3.14 add another twist to format specs: rather than being type dependent, "what works" depends on whatever code processes the Template instance. Unlike with f-strings, format() is not called automatically when t-strings are evaluated; in fact, there's no requirement that processing code does anything with the format specs at all. (Good processing code probably will want to do something!)
[0] https://docs.python.org/3/library/string.html#format-specifi...
T-strings use the exact same syntax as f‑strings, but their “format spec” (the part after the optional :, like .2f) can effectively be anything.
That might make creating a quiz tricky? With f‑strings, Python immediately calls format() on that spec; with t‑strings, it's simply captured in Interpolation.format_spec. It's up to your code to decide whether to call format() or do something entirely different with this value.
This is silly and seems to discount the massive Python codebases found in "real production environment"s throughout the tech industry and beyond, some of which are singlehandedly the codebases behind $1B+ ventures and, I'd wager, many of which are "robust" and fit for "industrial use" without babysitting just because they're Python.
(I get not liking a given language or its ecosystem, but I suspect I could rewrite the same reply for just about any of the top 10-ish most commonly used languages today.)
In practice, it’s hard! You’re effectively responsible for building a sync engine, handling conflict resolution, managing schema migration, etc.
This said, tools for local-first software development seem to have improved in the past couple years. I keep my eye on jazz.tools, electric-sql, and Rocicorp’s Zero. Are there others?
The post-mortem for this is going to be quite a read. Hugops to all involved.
In any case, there is a slide in the talk that has both the Pydantic and SQL Alchemy logos. As far as I know, there’s only one (somewhat popular) library that ties these two together. I think the speaker makes a persuasive case that data, domain, API, and other models should remain related but distinct.
Then you already use levers to build code.
LLMs are a new kind of tool. They’re weird and probabilistic and only sometimes useful. We don’t yet know quite how and when to use them. But they seem like one more lever for us to wield.
You can't; they're different types. t-strings are not `str`
It's up to good framework/API design to take advantage of this.
I didn’t explicitly mention this in my post but, yes, the Template type is designed with caching in mind. In particular, the .strings tuple is likely to be useful as a cache key in many cases.
I understand why this seems strange at first!
As Paul mentioned, we spent quite a lot of time considering these issues as PEP 750 came together. In the end, we concluded (a) the PEP leaves open quite a few potential approaches for tools to adopt (not just the one you suggest, as others here have pointed out), and (b) it's ultimately something that the broader tooling community needs to rally around and should probably be out of scope for the PEP itself.
So, with that background in mind, I am indeed hopeful we'll see the ecosystem adapt! :-)
I see each of these as distinct but overlapping; I'm (slowly) writing a guide to string formatting with all of these in mind, trying to emphasize when I'd choose one over the other. (fwiw I personally avoid % and + these days; $ is pretty uncommon in practice; f-, t-, and .format() all seem to have good unique uses.)
But yes, the PEP leaves open an important question: how will tools decide to work with common types of content in t-strings, like HTML or SQL?
There are simple approaches that can be taken in the short term (content sniffing) and more robust approaches (type annotations, perhaps) that will take time and the broader tooling community to develop.
PEP 750's `string.templatelib.Template` is a separate and unrelated type. Amongst many differences, unlike PEP 292, `Template` has a literal form too.
I'm hopeful that the confusion will be minimal; in practice, PEP 292 (aka $-strings) is used only in specialized cases, like flufl.i18n, a really deep I18N framework.
(As to your initial example: it's worth considering what will happen as you compose multiple bits of HTML via nesting to generate a large final page. The developer experience may become... unideal.)
* (barring undesirable hacks with inspect, etc.)
I'm a little late to the conversation (and a bit surprised to see this trending on HN) but am happy to answer any questions; I'll try to pop in throughout the day.
I’m curious how?