32 comments

[ 2.5 ms ] story [ 88.2 ms ] thread
I was so into Python for 10 years, was enjoyable to work in. But have deleted 100k+ lines this year already moving them to faster languages in a post AI codebot world. Mostly moving to go these days.
From this example:

    lazy from typing import Iterator

    def stream_events(...) -> Iterator[str]:
        while True:
            yield blocking_get_event(...)

    events = stream_events(...)

    for event in events:
        consume(event)
Do we finally have "lazy imports" in Python? I think I missed this change. Is this also something from Python 3.15 or earlier?
Python has had lazy imports from like day one, where you could have an import statement in a function, and the library won't be imported until that function is hit.
It's one of the headline features of Python 3.15 (hence why it's not in this article). It's even mentioned as the first thing on the What's New doc, so I'm definitely counting it as a "headline feature".

Personally, can't wait. It was just this week that I observed a Python process running out of memory because a module import that's not being used during the process was added to the application, and the memory usage went over a critical threshold because of that.

> I've left this one to the bonus section because I've never used set operations on Counters and I'm finding it extremely hard to think of a use case for xor specifically. But I do appreciate the devs adding it for completeness.

Check out symmetric difference

https://en.wikipedia.org/wiki/Symmetric_difference

(comment deleted)
I am not a python dev but have the utmost respect for the ecosystem.

But damn, with all the supply chain attacks now in the news, could they just make a simple way (for non python insiders) to install python apps without fearing to be infected by a vermin with full access to my $HOME ...

There are plenty of python apps that you can just apt install. You probably don't even realize some of the apps you run are written in python?

And any app you run has access to $HOME, that's not a python specific thing. Look into apparmor or selinix if you want finer grained security

funny how we may have to wait even longer for llms to pick up this update in their pre-training
Thread safe ittertors? really are we still on these topics

lazy from typing import Iterator

def stream_events(...) -> Iterator[str]: while True: yield blocking_get_event(...)

events = stream_events(...)

for event in events: consume(event)

Oh, my beloved Python, for nearly 15 years I wrote you. I miss you, but I no longer do — it's not your fault, life has changed.
Is anyone working on a more capable Python-like language which also interfaces well with Python but without the baggage?
One of the Counter examples is incorrect, tested on both 3.13 and 3.15.0a

  >>> from collections import Counter 
  >>> c = Counter(a=3, b=1)  
  >>> d = Counter(a=1, b=2)   
  >>> c-d  
  Counter({'a': 2})
I noticed that as well. Per the docs:

  Several mathematical operations are provided for combining Counter objects to produce multisets (counters that have counts greater than zero). Addition and subtraction combine counters by adding or subtracting the counts of corresponding elements. Intersection and union return the minimum and maximum of corresponding counts. Equality and inclusion compare corresponding counts. Each operation can accept inputs with signed counts, but the output will exclude results with counts of zero or less.
Anyway, nice Counter-example ;-)
> Iterators, async functions and async iterators don't work well here because they have different semantics to standard functions. When you call them they return immediately with a generator object, coroutine function and async generator object respectively. So the decorator completes immediately as opposed to the entire lifecycle what it's wrapping.

> This is an unfortunate problem I've encountered many times, and it's often a problem for normal decorators too. But this has changed in 3.15, now the ContextDecorator will check the type of the function it's wrapping and ensure that the decorator covers the entire lifespan.

I very much like the idea of that change - but it also seems kind of dangerous, to do this with no "opt-in mechanism", as that quite subtly changes the behavior of existing usage sites.

This is a bit of a "spacebar heating" situation, because someone would have to intentionally use a decorator in the old, broken way, but if someone actually did that, things may unexpectedly break.

I come to Python around version 1.5, painfully tired by debugging CGI scripts, created by wannabe perl-golfers. Unfortunately, I feel like Python is losing more and more of the zen that once tempted me...

Lazy loading looks like a last nail in the coffin, where my love to Python was buried, although it was a long, tiresome process.

It's now being used by a lot of people because they have to rather than want to so there is a desire to ** it up and reinvent their favorite language by adding all sorts of warts. That's the price of success.

A proper revenge would be to introduce "easy mode" to Rust - where the compiler takes a huge chill pill and you get non-enforced garbage collection. :-)

Note that 3.15 is not released yet. It will come out in 4 months
The `except*` improvements are underrated. Been using ExceptionGroup in a CLI tool that wraps Semgrep — catching multiple subprocess errors cleanly in one block made the retry logic much simpler.
Why does every language need every feature? Python has completely lost its charm.
It's too popular and the people channeled into using it don't care about it other than to complain about why it isn't <insertlanguagehere>
I used to be obsessed about language design and now, since I almost never write code directly (it's always Claude), I completely lost interest.

It feels like a total waste of time and I wonder if other feel the same.

One of the consequences of the LLM tsunami might be the freezing of research and development in programming languages.

Maybe we'll be stuck with J's and python forever...

Presumably you don't really enjoy programming but the mistake would be to think that everyone doesn't.
> Immutable JSON Objects With the addition of frozendict in 3.15, we now have the ability to represent all the json types (array, boolean, float, null, string, object) in immutable (hashable) forms.

I actually love this last feature !!

These smaller features often end up being the most useful. I'm especially interested in testing the new standard library additions in my current projects.
Absolutely serious question: is anybody actually writing code anymore? (Reviewing it, architecting it, sure -- we do that). But writing code? If NOT, then seems to me, what we want in our LLM output is CODE THAT IS TRIVIAL TO UNDERSTAND (I apologize for shouting from the rooftops.)

I'm not sure adding 'features' to Python anymore makes sense - UNLESS those features help humans understand LLM code. Part of the problem is, of course, that LLMs haven't been trained on the latest-and-greatest, so they won't output any of it (even new training events won't capture the latest very much, since there is so little of it relative to what is already out there).

But again -- do new features help HUMANS understand what the LLMs produce? If not, seems to me ... new features merely add complexity for no apparent gain. (Or am I confused about this?) THANKS for any helpful opinions.

Wow, the Python folks do not want to entertain different goals for the language, it would seem. I still remain interested in whether it makes sense to add features to Python anymore, given that LLMs write all the code. Unless, as I said, such features enhance human comprehension (since we have to review the code the LLM produces).
If you don't write code you won't understand what you're reviewing. Any manager discovers this - their ability to review atrophies.