Hacker Newsnew | past | comments | ask | show | jobs | submit | dagenix's commentslogin

The problem, IMO, with asyncio is that its way, way too complicated. In my experience, anyio (https://github.com/agronholm/anyio) provides a much better interface on top of asyncio. And since it can use asyncio as a backend, it maintains compatibility with the asyncio ecosystem. FastAPI, for example, uses anyio.

One thing that I don't see being mentioned in any of the threads here talking about green threads is cancellation. A huge benefit, IMO, of anyio is that it makes cancellation really easy to handle. With asyncio, cancellation is pretty hard. And with green threads, cancellation is often impossible.


In my experience, the key to using asyncio is to use anyio. Anyio is an interface that you can use ontop of asyncio and fixes most of its shortcomings.

https://anyio.readthedocs.io


> This approach eliminates the need for complex setup tools like requirements.txt or package managers...

And yet, the rest of the article is about uv. According to uv itself:

> An extremely fast Python package and project manager, written in Rust.

It's a package manager!


A package manager that is a quick and snappy binary that doesn't need a big runtime, unlike most of the Python tools.


What exactly is your standard for "big"?

    $ du ~/.local/pipx/venvs/uv/bin/uv | cut -f 1
    38812
Stripped and dynamically linked, BTW. Compare the system-provided Python:

    $ du /usr/bin/python3.12 | cut -f 1
    7832
(But also, if you hope not to pay the cost of a Python runtime, what is your remaining use case for uv?)


Seems like you're dismissing the uv single file setup approach without fully understanding it. I'd recommend giving it a try. It's indeed simpler and snappier than any other package manager to date.


Python is fun again!! Omg it’s like when I first started with python before I knew all the pitfalls that were coming. Uv just makes it work again(unaware of all uv pitfalls atm, don’t spoil it for me yet:)


I'm not dismissing uv, I'm critiquing the article.


So, a hackier version of Tesla's autopilot? Sounds, uh, terrifying.


I especially like how there is next to no mention about safety on the main page. But at least its only $999 and it has AI and 50k GitHub stars, so, thats nice.


They have a basic safety page in the docs [0], which unfortunately has a dead link to their vehicle safety definitions due to a recent PR [1], along with some other safety-related deadlinks in the panda README. Avoiding having to deal with safety is a pretty integral part of their whole process though. They run some basic static analysis/sanitizers/unit tests, and everything past that is out of scope. If you're not okay with that level of verification for your steering control, it's probably not the product for you.

[0] https://docs.comma.ai/concepts/safety/

[1] https://github.com/commaai/panda/pull/2143


What’s with the snark?


I think it did much better on safety in some tests (no I don't have sources, going from memory :/), but is less capable by design on some more trickier scenarios. Basically pretty much what you would something like this to be.


It doesn't seem like https://comma.ai/ has sources either.



If by terrifying you mean totally awesome, I agree!


They don't call it "full self driving", that's a good start


Not as terrifying as humans


Meh...AP and Comma are driver aids. They're only supposed to reduce the mental load of driving on the highway, not be complete autonomous driving systems.

They're nothing more than traffic aware cruise control with automatic lane keeping. They're not designed to be used on surface streets, and certainly not intended to allow you to read a book or something while driving.


The pretty significant updates to MacOS support are really cool to see!



The funny thing with debit/credit wall: only long dead Italian merchchants knew its purpose.


I don't believe its in the standard library for Rust, even if it is very popular in the Rust ecosystem.


Right; I'm not super-familiar with Rust and how exactly they organise things, but it's in more or less every Rust project due to Cargo.toml.


Java does jit


Yes, JIT was not the right terminology to use. I lazily wrote JIT. Apologies. What I meant to convey was the difference in startup times and run time between running something in JVM and V8. Java feels heavy but in javascript ecosystem it feels so nimble.


Native Java via GraalVM starts up in milliseconds.


And it has to go through slow compilation step. With Node you can have a cake and eat it too.


You can't be serious about comparing the technological capabilities of the JVM and Node and objectively declare the latter as the winner.

Compilation times are also an absolute non-issue.

You don't compile for development. You do it for production (in the rare circumstances that you need it).


That's not what I am trying to convey here. JVM is amazing and it is a feat that java is as fast as it is and javascript and v8 are order of magnitude slower.

Also even though I also found java too verbose, I kept believing that we need it to be so to write good software. I still enjoy java but it doesn't compare to the ergonomics of typescript for me. And nimbleness of the experience according to me plays a decent role.

Currently for me, either I really care about performance and I default to rust for those applications or I need solutions where the product will evolve quickly over time and I need great DX over performance and I default to typescript for those.

Java definitely has a role to play but its role in my work has certainly diminished.


It does not "have" to go through such a step, by the way, because you can simply run such code on the JVM.


You're saying it like it's an absolutely good thing. Some (many?) users would rather pay the cost upfront in compilation time (doesn't really matter if it's AOT or JIT) than pay the same cost many times over through a significantly slower runtime. JVM also scales up to supercomputers (and everything in between) if you want it to, so depending on your requirements a single-threaded alternative might not even be an option.


I’ll use C++ or Rust for such use cases.


Okay!


As I understand it, if your code would have race conditions with free threaded python, than it probably already has them.


Not when there's a global interpreter lock.


The GIL does not prevent race conditions in your Python code. It only prevents race conditions in internal data structures inside the interpreter and in atomic operations, i.e., operations that take a single Python bytecode. But many things that appear atomic in Python code take more than one Python bytecode. The GIL gives you no protection if you do such operations in multiple threads on the same object.


I think what many will experience, is that they want to switch to multithreading without GIL, but learn they have code that will have race conditions. But that don't have race conditions today, as it's run as multiple processes, and not threads.

For instance our webserver. It uses multiple processes. Each request then can modify some global variable, use as cache or whatever, and only after it's completely done handling the request the same process will serve a new request. But when people see the GIL is gone, they probably would like to start using it. Can handle more requests without spamming processes / using beefy computer with lots of RAM etc.

And then one might discover new race conditions one never really had before.


I answered in a sibling reply: https://news.ycombinator.com/item?id=40950798


I'll respond there.


I’m a dummy don’t know nothing about coding but I love HN usernames lol


Are you writing an extension or Python code?

If you are writing Python code, the GIL can already be dropped at pretty much any point and there isn't much way of controlling when. Iirc, this includes in the middle of things like +=. There are some operations that Python defines as atomic, but, as I recall, there aren't all that many.

In what way is the GIL preventing races for your use case?


It is not about your code, it is about C extensions you are relying on. Without GIL, you can't even be sure that refcounting works reliably. Bugs in C extensions are always possible. No GIL makes them more likely. Even if you are not the author of C extension, you have to debug the consequences.


Does that mean rewriting all the extensions to Rust? Or maybe CPython itself?

Would that be enough to make Python no gill viable?


I mean that, if the GIL didn't prevent races, it would be trivially removable. Races that are already there in people's Python code have probably been debugged (or at least they are tolerated), so there are some races that will happen when the GIL is removed, and they will be a surprise.


The GIL prevents the corruption of Pythons internal structures. It's hard to remove because:

1. Lots of extensions, which can control when they release the GIL unlike regular Python code, depend on it 2. Removing the GIL requires some sort of other mechanism to protect internal Python stuff 3. But for a long time, such a mechanism was resisted by th Python team because all attempts to remove the GIL either made single threaded code slower or were considered too complicated.

But, as far as I understand, the GIL does somewhere between nothing and very little to prevent races in pure Python code. And, my rough understanding, is that removing the GIL isn't expected to really impact pure Python code.


Hmm, that's interesting, thank you. I didn't realize extensions can control the GIL.


Yup, I think its described here: https://docs.python.org/3/c-api/init.html#releasing-the-gil-....

My understanding, is that many extensions will release the GIL when doing anything expensive. So, if you are doing CPU or IO bound operations in an extension _and_ you are calling that operation in multiple threads, even with the GIL you can potentially fully utilize all of the CPUs in your machine.


> removing the GIL isn't expected to really impact pure Python code.

If your Python code assumes it's just going to run in a single thread now, and it is run in a single thread without the GIL, yes, removing the GIL will make no difference.


> If your Python code assumes it's just going to run in a single thread now, and it is run in a single thread without the GIL, yes, removing the GIL will make no difference.

I'm not sure I understand your point.

Yes, singled thread code will run the same with or without the GIL.

My understanding, was that multi-threaded pure-Python code would also run more or less the same without the GIL. In that, removing the GIL won't introduce races into pure-Python code that is already race free with the GIL. (and that relatedly, pure-Python code that suffers from races without the GIL also already suffers from them with the GIL)

Are you saying that you expect that pure-Python code will be significantly impacted by the removal of the GIL? If so, I'd love to learn more.


> removing the GIL won't introduce races into pure-Python code that is already race free with the GIL.

What do you mean by "race free"? Do you mean the code expects to be run in multiple threads and uses the tools provided by Python, such as locks, mutexes, and semaphores, to ensure thread safety, and has been tested to ensure that it is race free when run multi-threaded? If that is what you mean, then yes, of course such code will still be race free without the GIL, because it was never depending on the GIL to protect it in the first place.

But there is a lot of pure Python code out there that is not written that way. Removal of the GIL would allow such code to be naively run in multiple threads using, for example, Python's support for thread pools. Anyone under the impression that removing the GIL was intended to allow this sort of thing without any further checking of the code is mistaken. That is the kind of thing my comment was intended to exclude.


> But there is a lot of pure Python code out there that is not written that way. Removal of the GIL would allow such code to be naively run in multiple threads using, for example, Python's support for thread pools.

I guess this is what I don't understand. This code could already be run in multiple threads today, with a GIL. And it would be broken - in all the same ways it would be broken without a GIL, correct?

> Anyone under the impression that removing the GIL was intended to allow this sort of thing without any further checking of the code is mistaken. That is the kind of thing my comment was intended to exclude.

Ah, so, is your point that removing the GIL will cause people to take non-multithread code and run it in multiple threads without realizing that it is broken in that context? That its not so much a technical change, but a change of perception that will lead to issues?


> This code could already be run in multiple threads today, with a GIL.

Yes.

> And it would be broken - in all the same ways it would be broken without a GIL, correct?

Yes, but the absence of the GIL would make race conditions more likely to happen.

> is your point that removing the GIL will cause people to take non-multithread code and run it in multiple threads without realizing that it is broken in that context?

Yes. They could run it in multiple threads with the GIL today, but as above, race conditions might not show up as often, so it might not be realized that the code is broken. But also, with the GIL there is the common perception that Python doesn't do multithreading well anyway, so it's less likely to be used for that. With the GIL removed, I suspect many people will want to use multithreading a lot more in Python to parallelize code, without fully realizing the implications.


> Yes, but the absence of the GIL would make race conditions more likely to happen.

Does it though? I'm not saying it doesn't, I'm quite curious. Switching between threads with the GIL is already fairly unpredictable from the perspective of pure-Python code. Does it get significantly more troublesome without the GIL?

> Yes. They could run it in multiple threads with the GIL today, but as above, race conditions might not show up as often, so it might not be realized that the code is broken. But also, with the GIL there is the common perception that Python doesn't do multithreading well anyway, so it's less likely to be used for that. With the GIL removed, I suspect many people will want to use multithreading a lot more in Python to parallelize code, without fully realizing the implications.

Fair


> Switching between threads with the GIL is already fairly unpredictable from the perspective of pure-Python code.

But it still prevents multiple threads from running Python bytecode at the same time: in other words, at any given time, only one Python bytecode can be executing in the entire interpreter.

Without the GIL that is no longer true; an arbitrary number of threads can all be executing a Python bytecode at the same time. So even Python-level operations that only take a single bytecode now must be protected to be thread-safe--where under the GIL, they didn't have to be. That is a significant increase in the "attack surface", so to speak, for race conditions in the absence of thread safety protections.

(Note that this does mean that even multi-threaded code that was race-free with the GIL due to using explicit locks, mutexes, semaphores, etc., might not be without the GIL if those protections were only used for multi-bytecode operations. In practice, whether or not a particular Python operation takes a single bytecode or multiple bytecodes is not something you can just read off from the Python code--you have to either have intimate knowledge of the interpreter's internals or you have to explicitly disassemble each piece of code and look at the bytecode that is generated. Of course the vast majority of programmers don't do that, they just use thread safety protections for every data mutation, which will work without the GIL as well as with it.)


> if the GIL didn't prevent races, it would be trivially removable

Nobody is saying the GIL doesn't prevent races at all. We are saying that the GIL does not prevent races in your Python code. It's not "trivially removable" because it does prevent races in the interpreter's internal data structures and in operations that are done in a single Python bytecode, and there are a lot of possible races in those places.

Also, perhaps you haven't considered the fact that Python provides tools such as mutexes, locks, and semaphores to help you prevent races in your Python code. Python programmers who do write multi-threaded Python code (for example, code where threads spend most of their time waiting on I/O, which releases the GIL and allows other threads to run) do have to use these tools. Why? Because the GIL by itself does not prevent races in your Python code. You have to do it, just as you do with multi-threaded code in any language.

> Races that are already there in people's Python code have probably been debugged

Um, no, they haven't, because they've never been exposed to multi-threading. Most people's Python code is not written to be thread-safe, so it can't safely be parallelized as it is, GIL or no GIL.


That may be your definition, but that's not everyone's definition. Wikipedia, for example, says:

> Open-source software (OSS) is computer software that is released under a license in which the copyright holder grants users the rights to use, study, change, and distribute the software and its source code to anyone and for any purpose.

https://en.m.wikipedia.org/wiki/Open-source_software


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: