Python 3.13
Hey, I see Python 3.13 was released yesterday. Let's try it!
❯ cd ~/.pyenv
❯ git pull
❯ pyenv install -l | rg 3.13
3.13.0
3.13.0t
3.13-dev
3.13t-dev
...
❯ pyenv install 3.13
Downloading Python-3.13.0.tar.xz...
-> https://www.python.org/ftp/python/3.13.0/Python-3.13.0.tar.xz
Installing Python-3.13.0...
Installed Python-3.13.0 to /home/tim/.pyenv/versions/3.13.0
❯ pyenv global 3.13
❯ python
Python 3.13.0 (main, Oct 8 2024, 07:32:59) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 2 + 3
5
One of the things Python 3.13 has is a new REPL. Among other things, it has fancy colors. They didn't survive the cut and paste above, but here's what it looks like in my terminal

I think I need to install ruff for it too. That is, each version of Python I install needs its own ruff.
❯ pip install ruff
...
Besides the new REPL, there are two more big features in Python 3.13: "free-threading" (disabling the GIL) and JIT Compilation. Both of these are experimental.
It looks like the pyenv folks have compiled a free-threaded version for us, so we can try that out easy-peasy!
❯ pyenv install -l | rg 3.13
3.13.0
3.13.0t
3.13-dev
3.13t-dev
...
That first one, 3.13.0
, is what we installed above, the default GIL-enabled Python. But 3.13.0t
is the free-threaded version.
❯ pyenv install 3.13.0t
Downloading Python-3.13.0.tar.xz...
-> https://www.python.org/ftp/python/3.13.0/Python-3.13.0.tar.xz
Installing Python-3.13.0...
Installed Python-3.13.0 to /home/tim/.pyenv/versions/3.13.0t
❯ pyenv global 3.13.0t
We can see it used the same source code as above, but it was built
with the --disable-gil
option.
Does it work? Here's a silly program that uses threads.
#!/usr/bin/env python
import os
import threading
def fib(n):
return n if n < 2 else fib(n - 2) + fib(n - 1)
for _ in range(os.cpu_count()):
threading.Thread(target=fib, args=(35,)).start()
If we run it with the default version, it takes about a minute.
❯ pyenv global 3.13.0
❯ time ./fibonacci.py
real 1m5.690s
user 1m6.703s
sys 0m1.760s
But if we run it with the free-threading version, it takes just a few seconds.
❯ pyenv global 3.13.0t
❯ time ./fibonacci.py
real 0m5.694s
user 1m28.021s
sys 0m0.109s
This machine has 16 threads available.
>>> 65.690 / 5.694
11.536705303828592
It's about 12 times faster, rather than 16, but that's not bad.
With the default version, we were using all the threads, but they were taking turns. Here's the relevant bit of htop.

With the free-threading version, each thread stays busy.

When I'm interested in going fast, I'm probably not going to choose Python. But this does seem to work!