#488: tau - it's 2pi and it writes code
About the show
Sponsored by us! Support our work through:
- Our courses at Talk Python
- Consulting from Six Feet Up
Connect with the hosts
- Michael: Mastodon / BlueSky / X / LinkedIn
- Calvin: Mastodon / BlueSky / X / LinkedIn
- Show: Mastodon / BlueSky / X
Join us on YouTube at pythonbytes.fm/live to be part of the audience. Usually Tuesday at 7am PT. Older video versions available there too.
Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to our friends of the show list, we'll never share it.
Calvin #1: The trusted-publishing debate: how to do it right vs. why you shouldn't trust it
https://snarky.ca/how-to-publish-to-pypi-using-github-actions-securely/ (Brett Cannon) and https://blog.yossarian.net/2026/07/07/You-shouldnt-trust-trusted-publishing (William Woodruff)
- Trusted Publishing (PyPI's OIDC-based auth scheme, also now used by npm, RubyGems, crates.io, NuGet) replaces long-lived API tokens with short-lived, auto-scoped credentials tied to CI/CD machine identity.
- Yossarian's post: it's purely an authentication mechanism between a machine identity and a package — it says nothing about package safety or quality. PyPI deliberately avoids any "verified/trusted" badge for it, unlike its verified-URL checkmarks.
- Same logic applies to PyPI attestations: anyone can sign with any machine identity they control, so an attestation's presence isn't itself a trust signal.
- Bottom line from that post: don't confuse "trusted" (machine-to-machine) with "trustworthy" (human judgment about the package).
- Snarky.ca's companion piece is more practical: given GitHub Actions compromises in the news, the real fix is 3 concrete steps — run zizmor to lock down workflow permissions/checkout credentials and pin actions to commit hashes, adopt Trusted Publishing to eliminate stored PyPI tokens, and require manual approval via a GitHub environment before any publish job runs.
- Takeaway for listeners: Trusted Publishing is good hygiene for how you authenticate to PyPI, but it's not a substitute for securing your CI pipeline itself — or for actually vetting the packages you install.
Michael #2: JupyterLab 4.6 and Notebook 7.6 are out!
Michał Krassowski's rundown - a chunky minor release: 68 features, 97 bug fixes, 95 contributors, one of the biggest ever.
- Scratchpad console (Notebook 7.6 headliner) - a console next to your notebook sharing its kernel, for throwaway experiments. Ctrl+B.
- Jump to last-edited cell - new commands hop through recently edited cells.
- File browser glow-up - Date Created column, editable breadcrumbs with Tab-completion, and Open in Terminal.
- Debugger - sources open in the main area, floating step/continue overlay, live kernel-sources filter.
- Custom layouts (Lab) - activity bar top/bottom, draggable panels, four-way tab splits, per-panel Ctrl+scroll zoom.
- ~5x faster extension builds - webpack → Rspack, and
jupyter-buildermeans no full Lab install needed to build extensions. - Keyboard/a11y - add shortcuts from the UI (no JSON), Find & Replace in Edit menu (Ctrl+H).
Calvin #3: Tau – new small, readable terminal coding agent
- Tau – new small, readable terminal coding agent (Python 3.12+), built as both a working tool and a teaching project for how coding agents work under the hood
- Install via
uv tool install tau-ai,pipx, orpip; ships atauCLI - Three-layer architecture:
tau_ai(provider-neutral model layer) →tau_agent(reusable "brain": messages, tools, events, loop) →tau_coding(CLI/TUI, file & shell tools, sessions) - Supports OpenAI, Anthropic, OpenAI Codex, OpenRouter, Hugging Face, and custom/local OpenAI-compatible endpoints
- Built-in tools (read/write/edit/bash), durable JSONL sessions with resume/branching, project instructions via
AGENTS.md, and context compaction - Core harness is UI-agnostic — same brain can power the TUI, print mode, or a custom frontend — usable as a standalone library too
Michael #4: Django Tasks and Django 6.1
- Django 6.0 finally ships first-party background tasks (
django.tasks) - out of Jake Howard's DEP 14, accepted May 2024, after two decades of everyone bolting on Celery/RQ/Huey. - It's an API, not a worker. Django handles task definition, validation, queuing, and result storage - it does not execute them. You bring the backend.
- The default backend traps people.
ImmediateBackendruns tasks inline on the request thread and blocks until done - so out of the box.enqueue()backgrounds nothing (a 5-second task means a 5-second response). The other built-in,DummyBackend, runs nothing at all. Both are dev/test only. - Nice API otherwise: slap
@taskon a function, call.enqueue(), get back aTaskResultyou look up later by id - with async twins likeaenqueue(). Gotcha: args and return values must survive a JSON round-trip, so a tuple sneakily comes back as a list. - The community local backend to know:
django-tasks-localby Chris Beaven (SmileyChris). AThreadPoolExecutorbackend that gives real background threads with zero infrastructure - no Redis, no Celery, no database - plus aProcessPoolBackendfor CPU-bound work → github.com/lincolnloop/django-tasks-local - Its catch: results live in memory, so pending tasks vanish on restart or deploy. Great for dev and low-traffic production; for persistence, drop to Jake Howard's
django-tasks(DatabaseBackend + worker command).
Extras
Calvin:
- Fixing the dictionary with Python 3.14 — Hugo van Kemenade stumbled on - and got fixed - a markup bug in the OED's own citation of a 1706 use of the pi symbol.
Michael:
Jokes:
- What's the object-oriented way to become wealthy? Inheritance
- To understand what recursion is... You must first understand what recursion is
- 3 SQL statements walk into a NoSQL bar. Soon, they walk out They couldn't find a table.
Episode Transcript
Collapse transcript
00:00
00:13
00:15
00:28
00:30
00:33
00:40
00:42
00:44
00:50
00:53
00:54
00:56
00:59
01:06
01:08
01:08
01:14
01:17
01:20
01:25
01:34
01:48
01:59
02:12
02:23
02:28
02:34
02:45
02:46
02:48
02:51
02:51
02:53
02:56
02:57
03:03
03:16
03:23
03:27
03:30
03:38
03:52
04:07
04:10
04:16
04:19
04:26
04:40
04:45
04:54
04:59
05:06
05:13
05:20
05:23
05:33
05:34
05:35
05:38
05:39
05:41
05:43
05:43
05:48
05:54
05:54
06:01
06:06
06:06
06:11
06:14
06:14
06:15
06:15
06:25
06:26
06:29
06:35
06:35
06:36
06:37
06:42
06:43
06:47
06:47
06:47
06:49
06:52
06:53
06:58
07:00
07:02
07:02
07:08
07:19
07:21
07:25
07:26
07:34
07:36
07:40
07:41
07:42
07:46
07:48
07:50
07:57
08:00
08:03
08:04
08:05
08:06
08:07
08:09
08:11
08:12
08:13
08:17
08:18
08:19
08:21
08:22
08:28
08:29
08:33
08:38
08:41
08:48
08:49
08:51
08:55
08:57
08:59
09:03
09:09
09:12
09:17
09:21
09:22
09:28
09:29
09:33
09:36
09:39
09:43
09:47
09:57
09:58
10:02
10:03
10:07
10:13
10:18
10:21
10:23
10:25
10:29
10:30
10:31
10:33
10:34
10:35
10:37
10:41
10:44
10:46
10:48
10:51
10:52
10:53
10:57
10:58
10:59
11:04
11:09
11:11
11:12
11:15
11:27
11:33
11:34
11:35
11:36
11:40
11:45
11:46
11:50
11:55
12:01
12:03
12:09
12:15
12:22
12:29
12:39
12:51
12:54
12:56
12:57
13:00
13:03
13:04
13:17
13:30
13:40
13:55
14:07
14:13
14:22
14:27
14:40
14:51
14:52
14:55
15:02
15:08
15:09
15:15
15:17
15:20
15:25
15:37
15:47
15:53
16:04
16:18
16:27
16:39
16:49
16:58
17:13
17:27
17:42
17:48
17:53
17:58
18:12
18:17
18:18
18:18
18:19
18:21
18:22
18:25
18:27
18:36
18:39
18:40
18:43
18:43
18:44
18:45
18:48
18:50
18:54
18:59
19:01
19:07
19:13
19:28
19:43
19:57
19:58
20:01
20:04
20:09
20:10
20:12
20:18
20:19
20:20
20:29
20:31
20:36
20:41
20:49
20:55
20:56
20:57
20:59
20:59
21:01
21:02
21:04
21:07
21:13
21:15
21:21
21:27
21:29
21:34
21:38
21:40
21:42
21:44
21:51
21:55
21:56
21:58
21:59
22:02
22:07
22:08
22:20
22:22
22:23
22:29
22:35
22:38
22:40
22:49
22:50
22:53
23:01
23:02
23:11
23:17
23:23
23:23
23:28
23:31
23:40
23:44
23:46
23:47
23:49
23:50
23:57
23:59
24:01
24:03
24:03
24:04
24:05
24:08
24:11
24:20
24:27
24:28
24:33
24:34
24:36
24:41
24:44
24:45
24:47
24:48
24:50
24:55
24:55
24:56
24:57
24:57
24:58
24:59
25:00
25:03
25:04
25:07
25:19
25:22
25:25
25:28
25:37
25:39
25:41
25:54
25:57
25:58
26:00
26:01
26:02
26:03
26:04
26:06
26:07
26:07
26:14
26:19
26:21
26:22
26:24
26:27
26:28
26:30
26:32
26:34
26:36
26:37
26:38
26:39
26:40
26:52
26:58
27:03
27:12
27:13
27:17
27:21
27:22
27:23
27:23
27:26
27:29
27:32
27:36
27:44
27:45
27:46
27:57
28:00
28:01
28:02
28:03
28:05
28:06
28:07
28:16
28:18
28:19
28:20
28:21
28:23
28:30
28:31
28:36
28:37
28:38
28:39
28:40
28:43
28:49
28:52
28:53
28:54
28:55
29:00
29:02
29:05
29:06
29:07
29:07
29:08
29:09
29:12
29:13
29:15
29:15
29:21
29:23
29:29
29:30
29:31
29:38
29:45
29:45
29:50
29:56
30:10
30:19
30:33
30:38
30:44
30:46
30:49
30:50
30:51
30:52
30:53
30:54
30:57
30:58
30:59
31:00
31:02
31:04
31:06
31:13
31:18
31:33
31:44
31:56
32:03
32:08
32:08
32:09
32:10
32:13
32:14



