Python Bytes cover art

Python Bytes

Python Bytes

Written by: Michael Kennedy and Calvin Hendryx-Parker
Listen for free

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.Copyright 2016-2026 Politics & Government
Episodes
  • #500 Episode 500!
    Oct 14 2026
    Topics covered in this episode: A quick chat with Brian looking backExtrasJokeWatch on YouTube About the show Brian #1: A quick chat with Brian looking back Nick #2: Jev and the Case for Boring ML Vincent Warmerdam from marimo benchmarked Jev, a new "System 1" decision model from TypeSafe AI. In his video It handles classification without the latency or token cost of generative LLMs, which raises a practical question for data teams: where does this fit alongside traditional machine learning? He tested Jev against classical machine learning models to see if its speed and accuracy hold up on real-world datasets. General LLMs work well for reasoning, but generating full token streams just to assign a category adds unnecessary latency and cloud cost. Jev avoids generation entirely by evaluating the input and returning only the decision, which makes it much faster and cheaper than standard chat APIs. It consistently outperformed eight-shot sentence transformer setups like SetFit out of the box, especially on datasets with dozens of target categories. Traditional models like logistic regression still matter because they run in single-digit milliseconds on basic CPUs, cost nothing per inference, and keep private data within your own network. You cannot fine-tune Jev directly, so standard models remain the better choice when your data contains internal company acronyms, product names, or domain slang. The most practical approach is using Jev to bootstrap initial labels or audit bad training data, then training a small model you can own and run locally. Brett #3: Announcing the 2026 Python Packaging Council Election Results! The inaugural Python packaging council (PPC) has been elected and started meeting! Introduced via PEP 772 5 members elected Top 2 vote-getters get two-year terms Other 3 get one-year terms All members will get two-year terms going forward, staggering the elections There have been 4 meetings far as well as a meeting with the SC Initial meeting notes As the inaugural packaging council still working out basic logistics like how to take notes Also working out what the packaging council should do as PEP 772 explicitly says packaging.python.org falls under the PPC, but otherwise tries not to dictate what the PPC is in charge of Calvin #4: Parsing JSON at tens of gigabytes per second in Python Daniel Lemire (Oct 12) benchmarks fastsimdjson 0.6.0, a Python binding for simdjson on PyPI, repo at simdjson/fastpysimdjson. Its map_many function runs a callback per JSON line across N threads. Workload: Eight hours of GH Archive data, 7.6 GB and 2.2M events. The task counts event types and looks up the target repo's language for each opened PR, and it only touches a few fields per event. Lazy trick: With lazy=True, the whole event is parsed but Python objects are created only for the fields you access. The idea comes from Tyler Kennedy's pysimdjson. Single core: stdlib json gets 0.18 GB/s (about 42 s for the whole set), orjson 0.42, msgspec 1.29, fastsimdjson lazy 2.13 (3.6 s). 64 cores: stdlib json gets 3.17 GB/s, msgspec 24.6, fastsimdjson eager 29.8, and fastsimdjson lazy 65.7. That's the full 7.6 GB in about 0.12 s, roughly 31x its own single-core speed. Requires free-threading: It ran on Python 3.14.6 free-threaded (3.14t) on a 64-core dual-Xeon box. Grain of salt: It's one machine and one dataset. It's an embarrassingly parallel job with per-thread counters. The lazy win only shows up when you read a few fields from big objects. msgspec was handed a schema declaring only the needed fields. The post itself doesn't say whether this generalizes. Michael #5: Grinberg's annual benchmark says 3.15 is flat, but the JIT finally pays off Miguel Grinberg ran his annual release-eve benchmark, comparing Python 3.15.0rc3 against every interpreter back to 3.10, plus PyPy, Node.js, and Rust, using his usual two CPU-bound programs: recursive Fibonacci and bubble sort. The standard 3.15 interpreter lands within noise of 3.14 on his workloads, while the experimental JIT build is roughly 20 to 28 percent faster and finally beats the standard interpreter, which has not happened before. The free-threaded build holds up well in the 4-thread tests. He is candid that the workloads are just Fibonacci and bubble sort, and the official release lands days after his measurements. It is an independent, workload-based counterpoint to the official 7-8 percent JIT geometric-mean claim, from a series with real trend data back to 3.10. He did the same exercise for 3.12, 3.13, and 3.14, so there is a multi-year trend line to draw on. Methodology is two hand-picked CPU-bound programs, recursive Fibonacci plus bubble sort, not a pyperformance-style suite, which cuts both ways. PyPy 3.12 still runs circles around every CPython in the single-threaded tests, and Rust is about 77x faster on Fibonacci. The JIT gain is real in these numbers, but the JIT stays experimental, so he will not use it in production yet. Free-threaded fibo at 4 ...
    Show more Show less
    1 hr and 8 mins
  • #499 So many questions??
    Oct 6 2026
    Topics covered in this episode: PEP 824 brings ?? and ??= to Python for None handlingPython 3.15 gets a surprise RC3, and Python 3.10 reaches end of lifeasyncio.shieldPyxel: the retro game engine for PythonExtrasJokeWatch on YouTube About the show Sponsored by us! Support our work through: Our courses at Talk PythonConsulting from Six Feet Up Connect with the hosts Michael: Mastodon / BlueSky / X / LinkedInCalvin: Mastodon / BlueSky / X / LinkedInShow: 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 clobbereduser.name ??= "unknown" replaces the two-line check-then-assign pattern, with left-side subexpressions evaluated and cached exactly oncePrecedence sits between or and conditional expressions, matching JavaScript and C#, and ?? lands as a BoolOp in the AST next to and and orUnlike +=, ??= is a conditional assignment that skips the right side entirely, which is why it gets its own AST node rather than AugAssignStill 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...
    Show more Show less
    33 mins
  • #498 A Tiny Episode
    Sep 29 2026
    Topics covered in this episode: MemTensor / MemoryOS PyPI package hijacked via a malicious build backendTinyMongoJev: what to knowOne innocent dict read makes attribute access permanently slowerExtrasJokeWatch on YouTube About the show Sponsored by us! Support our work through: Our courses at Talk PythonConsulting from Six Feet Up Connect with the hosts Michael: Mastodon / BlueSky / X / LinkedInCalvin: Mastodon / BlueSky / X / LinkedInShow: 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/cachingJSON/TinyDB simple JSON filesSQLite for durable, high-perf reads with WALSQLIte shared for high write appsDuckDB + Parquet for analytics appsPostgres + MariaDB for multi-machine client/serverGreat for teaching, examples, and simple deploymentsAmazing 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 ...
    Show more Show less
    33 mins
adbl_web_anon_alc_button_suppression_t1
No reviews yet