Pular para o conteúdo
PodcastsNotíciasPython Bytes

Python Bytes

Michael Kennedy and Calvin Hendryx-Parker
Python Bytes
Último episódio

500 episódios

  • Python Bytes

    #499 So many questions??

    06/10/2026 | 32min
    Topics covered in this episode:

    PEP 824 brings ?? and ??= to Python for None handling

    Python 3.15 gets a surprise RC3, and Python 3.10 reaches end of life

    asyncio.shield

    Pyxel: the retro game engine for Python

    Extras

    Joke

    Watch on YouTube

    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.

    Michael #1: PEP 824 brings ?? and ??= to Python for None handling

    PEP 824, a new draft from Marc Mueller sponsored by Guido van Rossum, proposes None-coalescing operators for Python 3.16. The ?? operator returns its left-hand side unless that value is None, and ??= assigns a fallback only when the target is None. It revives the long-deferred PEP 505 from over a decade ago, trimmed to just these two operators, with None-aware access split off into PEP 823. The goal is replacing verbose is None checks with something closer to or, but keyed on None instead of truthiness.

    Every Python codebase has piles of if x is None fallback code, and this is the first serious move in ten years to give it real syntax.

    user.age ?? "unknown" is like or but only falls back on None, so 0, "", and [] pass through instead of getting clobbered

    user.name ??= "unknown" replaces the two-line check-then-assign pattern, with left-side subexpressions evaluated and cached exactly once

    Precedence sits between or and conditional expressions, matching JavaScript and C#, and ?? lands as a BoolOp in the AST next to and and or

    Unlike +=, ??= is a conditional assignment that skips the right side entirely, which is why it gets its own AST node rather than AugAssign

    Still draft status targeting 3.16, with a working reference implementation and an online demo to try, and it notably rejects a soft keyword like otherwise in favor of the familiar ??

    Discussion-worthy: the PEP answers the old objection that making None easier will proliferate its use, pointing out None is already everywhere and the status quo just produces uglier code

    # OG way
    user = db.get_user()
    city = None
    if user is not None:
    if user.address is not None:
    if user.address.city is not None:
    city = user.address.city

    # Michael's preferred way
    user = db.get_user()
    city = user?.address?.city

    Calvin #2: Python 3.15 gets a surprise RC3, and Python 3.10 reaches end of life

    The release team added a surprise third release candidate for Python 3.15 to fix last-minute lazy-import release blockers. They wanted time to test the fixes properly.

    That pushes the 3.15.0 final release from October 2 to October 9, 2026.

    RC3 has about 156 fixes from 82 contributors. The headline features are explicit lazy imports (PEP 810), the new frozendict (PEP 814) and sentinel (PEP 661) built-ins, and UTF-8 as the default encoding (PEP 686).

    No more ABI changes are coming, so library authors should be building 3.15 wheels now. uv 0.12.23 already added CPython 3.15.0rc3.

    On October 1, Python 3.10.22, 3.11.17, 3.12.15, 3.13.16 and 3.14.8 shipped together with nine common security fixes. They cover SSL validation, tarfile and zipfile handling, and urllib credentials.

    Python 3.10.22 is the final 3.10 release. After five years it gets no more security updates, so anyone still on 3.10 should upgrade.

    Python 3.13.16 is the last full maintenance release of 3.13, which now moves to security-only fixes. Only 3.13.16 and 3.14.8 have Windows and macOS installers, and the older releases are source-only.

    Python 3.11 gets security fixes through October 2027, and 3.12 through October 2028.

    A natural way to tie the two together: one version is nearly out the door and one is officially gone, and the same week is the time to test your code on 3.15 and move off 3.10.

    Michael #3: asyncio.shield

    Where async code can be cancelled

    In async Python, every await is a point where your coroutine can be stopped. If someone cancels the task, asyncio raises CancelledError at whichever await the coroutine is paused on, and nothing after that line runs.
    Quart does this on purpose. When the client disconnects, it cancels the request's task. From quart/asgi.py:

    elif message["type"] == "http.disconnect":
    self._disconnected = True
    request.body.disconnect()
    request_task.cancel()

    That's reasonable for a slow page nobody is waiting on anymore. It's a problem for a handler that writes to the database in two steps:

    await downloads.insert_one(event) # 1. log the download
    await totals.update_one(..., {'$inc': ...}) # 2. bump the episode's total

    A podcast app requests the MP3, gets what it needs, and hangs up. If it hangs up while step 2 is in flight, step 1 has already landed and step 2 never runs. Nothing is logged and nothing reaches Sentry, because a cancelled request isn't an error. The two collections just drift apart.
    Under WSGI this couldn't happen. A disconnect didn't stop your view; the view finished both writes and the server only failed later, when it tried to send the response.

    The demo

    I ran this on Python 3.14. The "client" hangs up 15 ms into a pair of 10 ms writes:

    async def record_download():
    await db_write('events')
    await db_write('total')
    _pending: set[asyncio.Task] = set()
    async def record_download_shielded():
    task = asyncio.create_task(record_download())
    _pending.add(task)
    task.add_done_callback(_pending.discard)
    await asyncio.shield(task)
    record_download events=1 total=0
    record_download_shielded events=1 total=1

    The unshielded version loses the increment. The shielded version finishes it, even though the request was cancelled. The full script is in the scratchpad as shield_demo.py if you want it for the show.

    What asyncio.shield does, and its traps

    shield(task) protects the inner task from a cancellation aimed at the outer one. The handler still gets CancelledError immediately, so nothing after that line runs, but the inner task keeps going until both writes finish. The traps:

    Keep a reference to the task. The event loop only holds weak references to tasks, so a task with no other reference can be garbage-collected mid-run. The asyncio docs warn about this. That's what _pending is for.

    Its errors go nowhere by default. If a shielded write fails after the handler has already been cancelled, nobody awaits the result. You only get a "Task exception was never retrieved" warning. Log errors from inside the task, or in the done callback.

    It doesn't survive a process shutdown. If the event loop is closing, as during a Granian worker recycle or a deploy, pending tasks are still cancelled. The window is tiny, but it isn't zero.

    It hides hangs. A shielded write to a stuck database lives forever. Put a timeout inside the shielded task (asyncio.timeout(...)), not outside it.

    It makes the pair finish, not atomic. A crash between the two writes still splits them. The real fix is one operation that can't half-happen. That's what the SQLite move gets: an insert and an upsert in one synchronous transaction, with no await in the middle. Shield is the right patch for the Mongo code until then.
    The general lesson: in async code, related writes made one after another are only as reliable as the client's patience. Before shipping something like that, check whether your framework cancels on disconnect. Quart does, and I believe Django 5's async views do too. I don't think Starlette cancels a plain endpoint, but I haven't checked any of these other frameworks' source, so verify them before you say it on air.

    Calvin #4: Pyxel: the retro game engine for Python

    Pyxel is a free, MIT-licensed retro game engine for Python, built and maintained by a single developer. It has been in development since 2018 and has passed 18,000 GitHub stars.

    It's modeled on classic game consoles and deliberately limits you to 16 colors and 4 sound channels, which keeps scope small and games finishable.

    Built-in editors cover pixel art, tilemaps, sound and music, so you can make the graphics, audio and game logic in one place.

    The engine is implemented in Rust and compiled to WebAssembly, but you write your games in plain Python.

    Pyxel Code Maker is a browser playground with a code editor, resource tools and a run button. It loads projects from local files, GitHub Gists or URLs, and saves back to a Gist for sharing.

    Games can also run on the web, so sharing one can be as simple as sending a link.

    It's a fun, low-barrier way into game development, good for beginners and for teaching kids.

    Extras

    Calvin:

    Python Lang Summit 2026 discusses a sys namespace

    Be Careful Updating Your Refrigerator
    Michael:

    New Siri is No Bueno

    Who out there is doing interesting work with sqlite and litestream? Trying to put an episode together on it.

    Tinymongo shoutout https://tinymongo.org

    Joke: I was there.
  • Python Bytes

    #498 A Tiny Episode

    29/09/2026 | 33min
    Topics covered in this episode:

    MemTensor / MemoryOS PyPI package hijacked via a malicious build backend

    TinyMongo

    Jev: what to know

    One innocent dict read makes attribute access permanently slower

    Extras

    Joke

    Watch on YouTube

    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: MemTensor / MemoryOS PyPI package hijacked via a malicious build backend

    On Sept 23 an attacker published backdoored MemoryOS 2.0.34 on PyPI and three bad versions (0.1.21, 0.1.23, 0.1.25) of MemTensor's OpenClaw plugin on npm. PyPI had no clean release that day, so 2.0.34 was the newest.

    They pushed commits to MemTensor's own GitHub Actions release pipelines. On PyPI that was a custom Poetry build backend, and on npm a tweaked validation script. Both used BASH_ENV to hand the publish token to the attacker before the real publish ran. SafeDep couldn't confirm how the attacker got push access.

    Runs on import, not install: A Go implant called sckit starts when the library loads, so --ignore-scripts won't save you.

    It harvests credentials from your home directory (npm and PyPI tokens, GitHub tokens, SSH keys, cloud CLI tokens, .env files) and sends them to skyleen[.]fr servers.

    It's a worm: It uses stolen tokens to copy itself into other repos and packages, so the victim list could grow.

    If you installed it: Downgrade to MemoryOS 2.0.33 (plugin 0.1.20) and rotate every credential reachable from $HOME. Also kill any running sckit stage0 process and check repos you can push to for a stray runtime-update.yml workflow or .sckit/ directory.

    Michael #2: TinyMongo

    Want to use a MongoDB data interface, but swap out the storage engine?

    Memory for testing/caching

    JSON/TinyDB simple JSON files

    SQLite for durable, high-perf reads with WAL

    SQLIte shared for high write apps

    DuckDB + Parquet for analytics apps

    Postgres + MariaDB for multi-machine client/server

    Great for teaching, examples, and simple deployments

    Amazing story of paired AI development

    Will completely run talkpython.fm after weeks of shared work together (in SQLite mode).

    Calvin #3: Jev: what to know

    What it is: Jev is a model from TypeSafe AI that answers with typed results (yes/no probabilities, scores, picks from your options) instead of prose. Real Python published a hands-on tutorial on 2026-09-24 and the buzz on hacker news is almost deafening.

    It's proprietary: Jev is a hosted, closed-weight model. There are no weights to download and no self-hosting. Everything called "open Jev" is an independent reimplementation, not TypeSafe's model.

    Your data leaves your machine: Every call sends your input text to a third-party API. In the tutorial that path goes through OpenRouter to TypeSafe. Think twice before sending customer messages, tickets or anything sensitive.

    Cost and stability are open questions: The tutorial calls Jev "cheap, but not free" and says it's fast and cheap "at the moment." It also says whether that stays true is "something to keep an eye on."

    Credit to Real Python: It's a good, practical intro. It shows the Noul, Score and Choice primitives, and its point that instruction wording matters more than thresholds is useful advice for any model. The tutorial itself says similar results are possible with a well-prompted LLM.

    Open options to look at instead:

    JevK5 (https://github.com/allebee/jevk5): Apache-2.0 weights and code, 4B or 9B parameters, and it accepts TypeSafe-style requests.

    SemIf, formerly OpenJev (https://github.com/TheoLeeCJ/openjev): MIT-licensed, small models, and it can run CPU-only.

    openjev-sglang (https://github.com/ekzhang/openjev-sglang): a Jev-compatible endpoint running Qwen3.6-35B-A3B, but no license is stated, so check before commercial use.

    The catch: These copy Jev's interface, not its model or training. Results will differ, and I haven't run any of them. Benchmarks are self-reported, and JevK5 is English-only.

    Michael #4: One innocent dict read makes attribute access permanently slower

    Timofei Ivankov benchmarks a CPython internals surprise: since 3.11, attribute access skips the instance dict entirely. A specialized opcode reads the attri.bute at a fixed byte offset in the object's inline values array. Read obj.__dict__ once, though, and the dict gets materialized, the object loses that specialized path for the rest of its life, and a million-iteration loop goes from 33 ms to 51 ms on CPython 3.14. vars() and copy.copy() trigger the same thing, so a debugging print or a shallow copy in code touching your hot objects quietly makes every later attribute access roughly 1.5x slower.

    The slowdown is permanent and nothing about it looks like a performance decision: ordinary code far from the hot loop can trigger it, and the function that gets slower never changes.

    Materializing dict produces a split table, and the LOAD_ATTR_WITH_HINT fallback declines split tables, so the object ends up with no specialization at all

    vars(), 'x' in o.dict, and copy.copy() all materialize it; copy.copy is the realistic trap since nobody treats a shallow copy as a performance decision

    slots instances read attributes at exactly the same speed and cannot fall into the trap since there is no dict to materialize

    On the free-threaded build both effects grow: atomic incref on reads plus an object lock on writes push the penalty from 17.6 to 25.4 ns

    Credit: this item was surfaced by the PyCoder's Weekly newsletter

    Extras

    Calvin:

    whatsnewt - a TUI text adventure through what's new in Python 3.15; playful but niche.

    Joke: Shipping a button in 2026…
  • Python Bytes

    #497 Faster than light profiling

    23/09/2026 | 26min
    Topics covered in this episode:

    Tachyon: A sampling profiler ships in Python 3.15's stdlib

    Python Workers are now generally available on Cloudflare

    Flet 1.0 - build cross-platform apps in Python

    marimo-book: Build static books from marimo notebooks

    Extras

    Joke

    Watch on YouTube

    Sponsored by Logfire from Pydantic: pythonbytes.fm/logfire
    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.

    Michael #1: Tachyon: A sampling profiler ships in Python 3.15's stdlib

    Python 3.15 adds the profiling package per PEP 799: profiling.tracing (where cProfile moved) and profiling.sampling, the new sampler called Tachyon

    py-spy and Austin exist but copy raw interpreter bytes with no API, so every CPython release risks breaking them; one in the stdlib is a contract to stop breaking profilers

    Defaults: 1 kHz, main thread, wall clock, and a -live top-like view for poking at a slow server

    Output is flexible: pstats, -flamegraph, -diff-flamegraph against a baseline, -heatmap on source lines, -opcodes for specialized bytecode, -gecko for Firefox Profiler with GIL and GC markers

    Profiling modes: wall, cpu, gil (which function is starving my other threads?), and exception, plus -async-aware to see the task graph instead of just select(), -all-threads, and -subprocesses forking a profiler per child

    Near-zero overhead for production; guidance is 10-30 second windows on representative load, and free-threaded builds divide the rate by thread count

    Attach to a running PID, same minor version only; ptrace permissions are the main friction. A 3.14 backport already exists on GitHub

    Caveat: it only sees Python frames, so 90% in calculate() hides NumPy underneath. For native stacks there's Cronon from HRT, 200k samples/sec over DWARF, not yet open source

    Calvin #2: Python Workers are now generally available on Cloudflare

    Python Workers are out of beta - now GA, "first-class" language on Cloudflare's Developer Platform

    No more manual JS interop: bindings (queues, R2, D1, Durable Objects) now work natively in Python, e.g. self.env.QUEUE.send({...})

    Runs on Pyodide (WASM-compiled Python), with real TCP socket support for DB connectivity

    Frameworks supported: FastAPI, Django, Flask; AI libs like OpenAI SDK, LangChain, MCP

    Underlying platform work formalized as PEP 783 (PyEmscripten), after a year of discussion

    Bottom line: write real Python on Cloudflare's edge, no JS glue code required

    Calvin #3: Flet 1.0 - build cross-platform apps in Python

    Flet hits 1.0 - build Flutter-backed apps from pure Python, no frontend experience needed

    One codebase targets six platforms: iOS, Android, Windows, macOS, Linux, web

    150+ built-in UI controls, plus support for custom controls / wrapping Flutter packages

    Mobile now supports real Python packages: NumPy, pandas, Pillow, cryptography

    Comes with pytest-based UI testing and an MCP integration for AI coding assistants

    Milestone lands 4+ years after its first PyPI release (Sept 2022) - signals "production ready," not experimental

    Michael #4: marimo-book: Build static books from marimo notebooks

    marimo-book is a Jupyter-Book-style static site generator built specifically for marimo .py notebooks. It ships polished multi-page sites with Material for MkDocs theming, full-text search, dark mode, and code copy, plus a content-hashed incremental build cache that drops rebuilds from 100+ seconds to roughly 3 seconds on real books. Standout extras include anywidget rendering without a kernel, static reactivity for discrete sliders via pre-rendered lookup tables, an opt-in WASM/Pyodide mode per chapter, and per-chapter launch buttons.

    If you've wanted to publish a marimo notebook as a real book or course site without hosting a kernel, marimo-book gives you the static, searchable, fast-loading output you'd expect from Jupyter Book.

    Alpha (0.1.x), but in production: pin marimo-book>=0.1.5,<0.2; the book.yml schema is stable for v0.1, and dartbrains.org is a real-world user.

    Two-stage build by design: a marimo-aware preprocessor emits plain Markdown + inline HTML, then mkdocs (Material today, zensical tomorrow) renders it. Not a mkdocs plugin, so the shell stays swappable.

    Interactive widgets without a kernel: anywidget Canvas/Three.js/Plotly mounts render statically, and mo.ui.slider with explicit steps gets pre-computed as a static lookup table.

    WASM escape hatch per chapter: set mode: wasm and the chapter routes through marimo's MarimoIslandGenerator, shipping the marimo runtime + Pyodide bundle for full reactivity where you need it.

    Per-chapter launch buttons and extras: readers can jump to molab, GitHub, or a downloaded .py; optional [social], [linkcheck], and [pdf] extras cover OG cards, htmlproofer, and WeasyPrint PDF export.

    Sandboxed notebooks: the sandbox mode reads PEP 723 inline metadata and provisions per-notebook envs via uv for portable builds, at the cost of slower first runs.

    Extras

    Calvin:

    Great overview of a new feature in Python 3.15 - frozendict

    Michael:

    Microsoft Plugs Nearly 1,000 Security Holes in Windows

    I’ll be speaking at PyBay 2026

    PyCon NL on October 15 in Utrecht

    Heading to Europe in October? PyCon NL is October 15th in Utrecht. One day, three tracks, about 350 people. It's an hour by train from Schiphol. There's also a session just for community organizers from groups like PyLadies, PyData, and Django. And the location fits. The Netherlands is where Python itself was born.

    Joke: You have homework (no really ;) )

    Watch Interview with Big Data engineer in 2026 by Kai Lentit
  • Python Bytes

    #496 A lake house in Seattle

    15/09/2026 | 32min
    Topics covered in this episode:

    Pandas Should Go Extinct

    Pydantic-pint puts real-world units in your Pydantic models

    How Libraries Run Rust Inside Python (With PyO3)

    AWS acquires DuckLabs

    Extras

    Joke

    Watch on YouTube

    Sponsored by Logfire from Pydantic: pythonbytes.fm/logfire

    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 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: Pandas Should Go Extinct

    Pandas' slowness pushes teams toward "Big Data" tools (Spark, Databricks) they don't actually need — most workloads never hit true Big Data scale

    Amazon Redshift telemetry: ~95% of tables are under 100GB, ~87% of queries touch 80GB or less — that's "Medium Data," not Big Data

    Polars and DuckDB fill that gap: single-machine, fast, no cluster required

    1 Billion Row Challenge benchmark: Pandas took 4m28s vs. Polars 5.04s and DuckDB 5.19s — DuckDB also used 19x less memory

    On a real-world NYC taxi dataset (3GB parquet), pure DuckDB ran 2x faster than pure Pandas while using a fraction of the RAM

    Bonus: Apache Arrow lets you pass data between Pandas/Polars/DuckDB with zero copying, so trying them out doesn't mean a full rewrite

    Michael #2: Pydantic-pint puts real-world units in your Pydantic models

    Pydantic-pint bridges Pydantic and Pint so models can validate physical quantities like 4m or 12 meters instead of bare floats. Fields annotated with PydanticPintQuantity parse user input, convert between compatible units, and serialize quantities back out as strings. That closes a real gap for anything consuming API payloads, config files, or sensor data with measurements, letting you enforce units at the validation boundary instead of hoping every caller remembered them.

    via PyCoder's Weekly newsletter

    Unit mix-ups have literally crashed spacecraft; now your Pydantic models can refuse them at the door.

    Annotate a field as Annotated[Quantity, PydanticPintQuantity('km')] and inputs like 12 meters arrive auto-converted to kilometers

    Validation covers string, numeric, and quantity inputs, and model_dump_json serializes quantities as readable unit strings

    Installable from PyPI as pydantic-pint, MIT licensed, with docs at pydantic-pint.readthedocs.io

    Early-stage solo project at version 0.4, so API stability and maintenance are open questions worth discussing

    Calvin #3: How Libraries Run Rust Inside Python (With PyO3)

    Pydantic v2's validation core (pydantic-core) is Rust under the hood, built with PyO3 — this post shows how that bridge actually works via a small hand-built JSON parser

    Four steps to get Rust into Python: write a normal Rust module, annotate with PyO3 macros (#[pyfunction], #[pymodule]), compile/install with maturin, then just import it

    The parser builds a Rust tree first — Python never touches it until the boundary crossing

    Key insight: converting the Rust result into Python objects (.into_pyobject) is often the expensive part, not the parsing — 100,000 JSON values means ~100,000 Python objects built after parsing's already done

    Errors cross the boundary too: Rust's typed errors convert into real Python exceptions (ValueError, FileNotFoundError) via From/?, so callers get clean Python semantics

    Takeaway for anyone porting Rust in: if you're returning a scalar, don't sweat it; if you're returning a big structure, profile the boundary — that's the real cost, not the algorithm

    Michael #4: AWS acquires DuckLabs

    Thank you Dylan McConnell.

    What does this mean for the DuckDB ecosystem?

    DuckDB is the open-source in-process analytical SQL engine. MIT licensed. The IP is not owned by any company - it's held by the nonprofit DuckDB Foundation, which was created when the team spun out of CWI Amsterdam. Peter Boncz, the CWI representative on the Foundation board, describes it as the entity that holds all IP of open-source DuckDB.

    DuckLabs (ducklabs.com) is the company, formerly branded DuckDB Labs. Founded a little over five years ago by Hannes Mühleisen and Mark Raasveldt to give the DuckDB team a stable long-term home, bootstrapped deliberately instead of taking VC, grown to 30+ people in Amsterdam, funded by support and feature-prioritization contracts. It employs the core devs. It does not own DuckDB.

    DuckLake is one of three projects DuckLabs builds, what they call the Duck Stack: DuckDB, DuckLake, and Quack. DuckLake is the lakehouse format that puts catalog metadata in a SQL database instead of in files on object storage. Quack is newer - an RPC-style protocol that turns DuckDB into a client-server system where both ends are DuckDB instances, slated to stabilize in DuckDB v2.0 in September 2026.

    MotherDuck is a separate Seattle company, Jordan Tigani's, selling serverless hosted DuckDB. It was started in partnership with DuckDB Labs and has worked closely with Hannes and Mark for four years. It contracted DuckLabs for engineering work and contributes heavily upstream - three of its engineers are among the top 10 outside contributors to DuckDB. It also sells its own DuckLake offering. Customer and collaborator, never owner.

    What the AWS post changes. Amazon bought the company, not the project. DuckLabs joined AWS effective September 1, with the process concluding August 31, 2026. Hannes and Mark keep leading the team and the project's technical direction, the team stays in Amsterdam, and DuckDB stays MIT under the Foundation. AWS gets the people and a direct line to the roadmap. The license protects your code, not your priorities.

    Three second-order effects worth tracking:

    The Foundation board is the real question. It has three directors: Mühleisen, Raasveldt, and Boncz. Two now work for AWS. Commentary on the deal has focused on exactly this - the license protects the code, not the roadmap. The announced counterweight is governance: a technical advisory board on the Foundation, and opening the extension stack so extensions signed by other developers can run in DuckDB.

    MotherDuck immediately moved into the business DuckLabs vacated. It now sells DuckDB enterprise support, which it had avoided because it didn't want to compete with DuckLabs' business model, and says it has explicit blessing from Hannes and Mark now that they're joining Amazon. It also bought Tower.dev the day before the AWS announcement.

    Everyone expects an AWS DuckDB service. Tigani says Amazon will likely release one eventually, and welcomes the competition, citing Redshift's failure to slow Snowflake on AWS. The groundwork is already visible: Amazon Quick uses DuckDB to query S3 Tables and has processed over 2.5B queries with it since launching in October 2025.

    The DuckLake angle is the one to watch. AWS is heavily committed to Iceberg through S3 Tables, and it just acquired the team behind a competing lakehouse format. The stated plan is to use DuckDB, DuckLake, and Quack together to power a new generation of data services, but which format wins internal priority is unannounced.

    Extras

    Calvin:

    astral-sh/uv 0.12.12: code-signed release binaries 🥳

    Michael:

    My MacBook power supply rebooted to install updates (?!?)

    The Story of VS Code | Official Documentary

    Amazon/AWS acquires DuckLabs (see recent episode on DuckLake)

    Joke: We’re agentic now
  • Python Bytes

    #495 Banned

    08/09/2026 | 27min
    Topics covered in this episode:

    EuroPython 2026 videos are online

    The State of Django 2026: Boring is so back

    htmx 4.0.0 has been released

    🐍 Functionally Zen

    Extras

    Joke

    Watch on YouTube

    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 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.

    Michael #1: EuroPython 2026 videos are online

    The EuroPython Society has published all 117 recordings from EuroPython 2026 on the official EuroPython Conference YouTube channel. The conference ran July 13-19 in Krakow, Poland and celebrated the conference series' 25th anniversary. The playlist covers keynotes, panels, lightning talks, and full talk recordings across Python core, web, DevOps, data/ML, embedded, and other tracks.

    If you missed EuroPython 2026 in Krakow, this is the complete free on-demand archive of one of the year's biggest European Python events.

    117 videos now live on the EuroPython Conference YouTube channel, last updated Aug 17, 2026.

    Michael’s personal watch list.

    Calvin #2: The State of Django 2026: Boring is so back

    State of Django 2026 (JetBrains/DSF survey, ~3,500 devs, 40+ countries) - "boring is so back": Django's core stays reliable while everything around it moves fast

    Core is stable: Postgres 76–79% for 5 years running, templates ~80%, 43% already on Django 6.0

    AI is routine now (only 10% use none) but workflow's unsettled - Claude Code leads at 35%, and 56% still just use it for chat, not autonomous edits

    Tooling is consolidating: uv and Ruff both at 43% adoption, each replacing several older single-purpose tools

    Type hints are winning (57% use them) but the checker is up for grabs - IDE-built-in leads at 40%, Mypy 32%, with ty/Pyrefly emerging

    Two Django communities coexist happily: 72% server-rendered templates vs. 53% API-only - and htmx adoption jumped from 5% to 34% in five years

    Michael #3: htmx 4.0.0 has been released

    After 8 months of work, the htmx team shipped 4.0.0, a rewrite that moves internals from XMLHttpRequest to fetch() while keeping the API almost identical to htmx 2. Three changes may need action: attribute inheritance is now explicit via an :inherited suffix, event names follow a htmx:phase:action pattern, and history no longer caches pages in localStorage. Additions include built-in morph swaps, the new hx-partial tag, and many core extensions. htmx 2 stays supported and remains latest on npm until early 2027.

    htmx is the go-to frontend layer for Python server-rendered apps (Flask, Django, FastAPI), and 4.0 is deliberately low-drama: nearly behavior-compatible, so teams can upgrade on their own schedule and pick up morph swaps and streaming extensions.

    Explicit inheritance is the biggest migration item: hx-confirm, hx-headers, hx-target and friends no longer cascade to children unless you append :inherited; hx-disinherit and hx-inherit are gone

    A CLI upgrade checker (npx htmx.org@4.0.0 upgrade-check) flags spots needing :inherited, renames like hx-disable to hx-ignore, removed attrs like hx-vars, and old event names in templates and JS

    Events follow htmx:phase:action (htmx:beforeRequest becomes htmx:before:request); most error events collapse into htmx:error and htmx:xhr:* events are removed with XMLHttpRequest

    History no longer snapshots pages in localStorage; back navigation re-fetches and swaps into the body, fixing a chronic support headache, with a new hx-history-cache extension for sessionStorage caching

    New features: out-of-the-box morphing swaps, the [HTML_REMOVED] tag for multi-element updates, streaming over SSE/WebSockets/multipart, and hx-live, their Alpine-inspired DOM scripting solution

    No forced upgrade: 2.x stays latest on npm until early 2027 (4.0 remains next) and is supported indefinitely; the team even ships official LLM skill files for guidance and upgrading

    Calvin #4: 🐍 Functionally Zen

    Functionally Zen (Kyle Adams, Test Double) - riffs on "simple is better than complex" with 7 extra tenets for Python simplicity

    Core claims: idiomatic > non-idiomatic, data > functions, pure functions > impure functions > classes

    Favorite example: a medical-dosage calculator replaced with a plain lookup dict - no logic, no tests needed

    Big idea: keep a thin "impure shell" around a "pure core" (Gary Bernhardt's functional core / imperative shell) - push side effects (API calls, DB, files) to the edges

    Side note: constructors that do I/O are "poison pills" - the side effect infects every class that depends on them

    Payoff: pure functions and no-mock tests are just easier to read and reason about than the alternative

    Extras

    Calvin:

    uv ships trusted-publisher token revocation and Python 3.15 support

    Making a Python interpreter in 1024 bytes

    Michael:

    Steering council voting is now open

    Joke: Makes you look like this?
Mais podcasts de Notícias
Sobre Python Bytes
Python Bytes is a weekly podcast hosted by Michael Kennedy and Calvin Hendryx-Parker. The show is a short discussion on the headlines and noteworthy news in the Python, developer, and data science space.
Site de podcast

Ouça Python Bytes, O Assunto e muitos outros podcasts de todo o mundo com o aplicativo o radio.net

Obtenha o aplicativo gratuito radio.net

  • Guardar rádios e podcasts favoritos
  • Transmissão via Wi-Fi ou Bluetooth
  • Carplay & Android Audo compatìvel
  • E ainda mais funções
Aplicações
Social
v8.23.3 | © 2007-2026 radio.de GmbH
Generated: 10/8/2026 - 1:21:01 AM