Épisodes

  • #504 Who turned the GIL back on?
    Nov 10 2026
    Topics covered in this episode: PyPI's redesigned project pages now warn when provenance changesgilguard catches the import that turns the GIL back onpip 26.3: pylock extras, and pip says plainly that untrusted wheels aren't safeAll developer toolsExtrasJokeWatch on YouTube About the show Sponsored by LongLink: Open-source platform for building and running custom business applications with Python and FastAPI 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: PyPI's redesigned project pages now warn when provenance changes Live now on pypi.org (Nov 6). Announced in July, shaped by user research, funded by OpenSSF and built by Kabu Creative.New Security tab on every project page shows each release's provenance state and per-file attestations, with a link to the transparency log.Two attestation types: PyPI Publish (uploaded by a Trusted Publisher) and SLSA Build Provenance (ties a file to its source commit, build platform and instructions)."No provenance" isn't a malware flag; it means the file's origin can't be cryptographically verified. That's typical for older releases or projects without Trusted Publishing.Four new provenance warnings: Incomplete (e.g. wheels via Trusted Publishing but sdist via API token), Inconsistent (mixed build systems or repos), Change (different repo or workflow than last release), Loss (stopped publishing attestations).Warnings are meant to catch files that may not have come from the maintainers, such as after an account or publishing-workflow takeover. PyPI says a Change of Provenance "can also indicate a compromised pipeline or account takeover," and an unexpected Loss of Provenance should be treated "with skepticism until verified.”Warnings now sit at the top of the page with yanked, archived and pre-release banners. A quarantine banner overrides all of them. Sidebar metadata is labeled "PyPI data" or "Data verified by PyPI."Release files tab gets search, filters, a per-file provenance column and orange icons for "late" files (uploaded more than 14 days after release). Those only appear on releases from before July 2026, when PyPI started rejecting new files after 14 days. Michael #2: gilguard catches the import that turns the GIL back on gilguard catches a nasty free-threading surprise: importing a C extension without declared free-threading support can turn the GIL back on for the rest of the process. Import gilguard first and it raises a detailed error naming the extension, distribution/version, import chain, and the line of your code responsible. A transitive dependency can undo your move to free-threaded Python. Fail at the offending import instead of discovering lost parallelism in a benchmark.Uses import hooks plus CPython's warning path to catch GIL activation; GILEnabledError inherits BaseException, so even except Exception won't swallow it.python -m gilguard audits installed top-level packages in fresh interpreters. Supports targeted modules and JSON output; exits 1 when it finds an offender for CI.The audit misses extensions loaded lazily on first use. Exercise those paths in tests with gilguard installed early; one process can identify only its first GIL-flipping import.GILGUARD_ACTION=warn reports without stopping; off permits standard builds. Default mode raises on standard Python or an already-enabled GIL. PYTHON_GIL=0 prevents activation, so the guard cannot detect offenders there.Published on PyPI as 0.1.0. Install with uv pip install gilguard. Python 3.13+, MIT; no runtime dependencies. Calvin #3: pip 26.3: pylock extras, and pip says plainly that untrusted wheels aren't safe pip 26.3 released Nov 2. Its security policy now says pip "has never considered installing untrusted wheels safe," because Python's import system is dynamic, so pip can't guarantee installing a wheel won't execute third-party code (#14412).The change: pip blocks unexpected imports during wheel installation "to avoid loading code from packages being replaced." It loads what it needs for installing and error reporting up front (PR #14247, merged Nov 2: https://github.com/pypa/pip/pull/14247).CLI vs. library use: from the command line, imports stay blocked until pip exits. Code that calls pip programmatically gets warnings after control returns.Rolled out in steps: pip 26.1 started warning ("Unexpected import of '...' after pip install started. pip 26.3 will enforce this behavior change"), and 26.3 turns it into an error. Tracking issue #13842 collected reports before enforcement: https://github.com/pypa/pip/issues/13842What tripped it in the wild: a .pth startup hook at ...
    Voir plus Voir moins
    30 min
  • #503 It’s not 85% HTML
    Nov 3 2026
    Topics covered in this episode: Your GitHub language bar is lying (how to fix it)Python Typing Survey 2026: developers mix type checkers, and AI is writing the hintsFlask Vibe - Build Apps You Can UnderstandPython on my wrist: MicroPython on a PineTimeExtrasJokeWatch on YouTube About the show Sponsored by us! Support our work through: Our courses at Talk PythonConsulting from Six Feet Up Connect with the hostsMichael: 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: Your GitHub language bar is lying (how to fix it) GitHub's language bar comes from Linguist, which counts every tracked byte in the repo. Michael's chameleon-rs project read as 75.5% HTML because committed docs-site output and test suites outweighed the Rust engine. Three .gitattributes attributes changed the story: linguist-generated for build output, linguist-vendored for an upstream test suite, and linguist-detectable=false for tests and benchmarks on both sides. The bar now shows the real mix, roughly 62% Rust and 38% Python. That bar is one of the first things people see on your repo; if generated files skew it, a few lines of .gitattributes tell the truth.The bar is byte-proportional, so a 9 MB committed docs build can make a Rust project read as mostly HTMLlinguist-generated hides build output and collapses those diffs in pull requests toolinguist-vendored covers copied-in code; linguist-detectable=false drops anything from the statschameleon-rs went from 75.5% HTML to roughly 62% Rust and 38% Python after a few lines of configTests and benchmarks were excluded symmetrically, on both the Rust and Python sides, so neither skews the ratioCheck patterns before pushing with git check-attr; GitHub recalculates a few minutes after the push Calvin #2: Python Typing Survey 2026: developers mix type checkers, and AI is writing the hints Meta's 2026 Python Typing Survey results: 1,794 responses, Aug 5 - Sep 2. Pyrefly (Meta), JetBrains, Microsoft and Astral's ty team helped write it.Typing is stable: 85.5% use hints often or always (88.0% in 2024). Which checker people use is not stable.49.9% run two or more checkers (46.0% in 2025), and 83.3% of Pyrefly users also run another one. Speed is the top reason for picking a checker (56.5%).Checkers disagree: 33.3% report inconsistencies between them, rising to 42.7% among multi-checker users.AI is writing the types: 42.5% had AI write hints, and 38.4% say types make AI code more reliable (18.5% last year).29.8% are "not sure" whether types help AI-assisted coding, about 4x the uncertainty on any other benefit.Help sources flipped: Stack Overflow 46.4% to 22.9% and LLM chat 26.0% to 41.7%, 2024 to 2026.Top pain is still missing library types (65.1%; Django, SQLAlchemy, pandas, NumPy). The most-wanted feature is better Callable syntax (45.7%). Raw data zip is linked. Michael #3: Flask Vibe - Build Apps You Can Understand Flask Vibe is a new tutorial site from Frederick Tubiermont, a developer who started coding at 47 and builds with Flask, PostgreSQL, raw SQL, and vanilla JS. The pitch: AI assistants generate more reliable, easier-to-verify code when the stack has no build step, no ORM, and no hydration. It ships a manifesto, tutorials on modular vanilla JS and AI-friendly coding patterns, and a Flask plus psycopg2 CRUD walkthrough. For vibe coders burned by Next.js defaults on Lovable or Replit, this is a concrete, opinionated case that simpler Python stacks pair better with AI-generated code.Claims a structural 1.8x LCP win over Next.js on the same dashboard app: 905ms vs 1.66s, both scoring Lighthouse 100Tutorials cover modular vanilla JS, AI-friendly coding patterns, and Flask CRUD with raw psycopg2 SQL and no ORMCreator started Python at 47 in 2022 and runs the site on the stack it teaches; the homepage is 42 KB with Lighthouse 100Solo London-based project (adsyme Ltd), launched via an r/flask self-post in February 2026; early, opinionated, and the benchmark leans on one self-run comparison with its methodology published on site Calvin #4: Python on my wrist: MicroPython on a PineTime Michiel (Python Leiden user group) runs MicroPython on a PineTime, Pine64's ~$26 open smartwatch: 64 MHz Cortex-M4, 64 KB RAM, 512 KB flash.He revived wasp-os, a dormant MicroPython watch OS stuck on a 2019 MicroPython fork whose maintainer is asking for new maintainers (issue #536).The build is now one command with uv. Bluetooth flashing uses bleak instead of the deprecated gatttool, cutting update time from over 8 minutes to about 3.5.Free RAM at boot went from 7.1 KB to 12.4 KB by using the flash chip's real 4 KB blocks. He also ...
    Voir plus Voir moins
    30 min
  • #502 Introducing chameleon-rs
    Oct 27 2026
    Topics covered in this episode: PHP wasn’t the only problem last weekchameleon-rsBringing uv and ty togetherStlite runs Streamlit apps entirely in the browserExtrasJokeWatch on YouTube About the show 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: PHP wasn’t the only problem last week Three security incidents in one week, each at a different layer: CA trust (eMudhra), the release pipeline (LiteLLM) and a C decoder (Brotli). All three have fixes released.eMudhra CA: the keys of a compromised eMudhra intermediate CA are now distrusted by CPython. 3.15.1, 3.14.9 and 3.13.17 shipped Oct 21. 3.15.2, 3.14.10, 3.13.18, 3.12.16 and 3.11.18 followed Oct 26 (CVE-2026-115557) and also fix a tarfile filter bypass. Python's post says pip operations are safe even before pip is upgraded.eMudhra, tooling: pip 26.2.2 bundles certifi 2026.10.19, which removes the root. uv 0.13.4 (GHSA-hq85-5cpj-mr62) and 0.13.5 (rustls-webpki 0.103.16) are the uv fixes. After upgrading uv, run uv python upgrade. Existing venvs need pip upgraded by hand, and the 3.9 and 3.10 builds still bundle a pip that trusts the root. Anyone holding those intermediate keys can mint certificates for any domain that an unpatched client will accept as valid.That enables man-in-the-middle attacks: reading or altering HTTPS traffic without a certificate warning.The risk is highest where the attacker can sit on the network path, such as hostile Wi-Fi, a compromised router or ISP, or a cloud network position.For Python specifically, the exposed traffic would be package downloads from PyPI, API calls with credentials or tokens, and webhooks. A tampered package download is the worst case.Containers and old venvs that nobody rebuilds are where this lingers. uv says its Python 3.9 and 3.10 builds still bundle a pip that trusts the root, and existing venvs don't pick up the fix automatically.LiteLLM 1.107.0: malicious wheels hit PyPI on Oct 21. All seven wheels were live from about 11:40 to 13:23 UTC, with roughly 49k downloads. The Docker images were also infected. It's the second LiteLLM compromise this year, after 1.82.7 and 1.82.8 in March.LiteLLM payload: cook.pth runs on every Python start, so nothing has to import litellm. It steals SSH, cloud, browser, CI and AI-tool credentials, and an hourly loader runs remote code. The clean pin is litellm==1.106.4. Kill the loader first, rebuild rather than repair, then rotate everything the host could reach.LiteLLM root cause: a master key committed to a public repo on May 27 was never revoked. On Oct 10 it yielded an org owner's GitHub CLI token. The attacker then changed the trusted release workflow to build from a lookalike Berri-AI/litellm repo. BerriAI's first explanation (tokens in logs) was wrong, and the Oct 23 report supersedes it.Broccoli2Shell: CVE-2026-111497 is an out-of-bounds write in Google's Brotli C decoder. It affects the Python Brotli and brotlicffi packages 1.0.3 through 1.2.0(.x). Upgrade to Brotli 1.2.1 or brotlicffi 1.2.1.0. The CVE was published Oct 22 and rated 9.2 Critical by GitHub.Broccoli2Shell workaround: if you can't upgrade, uninstall both packages. urllib3, requests and aiohttp then fall back to gzip and deflate. Also reject Content-Encoding: br request bodies at the proxy or WAF. Sourceshttps://blog.python.org/2026/10/python-3152-31410-31318-31216-31118/https://www.stepsecurity.io/blog/litellm-1-107-0-compromised-pypi-backdoored-wheels-credential-stealerhttps://broccoli2shell.com/ Michael #2: chameleon-rs Chameleon templates, much faster than before (up to 70x faster on start)Modernized: A Rust engine that runs your Chameleon templates unchanged with async rendering, partials (think HTMX), MarkdownBuilt-in framework support: Flask, Quart, FastAPI, Starlette, Pyramid, Robyn and Litestar integrations.A compatibility shim for testing out quickly: chameleon_rs.compat.install()AI agent support via docs (every doc page has a .md extension variant, eg FastAPI docs) and the skill is installable or downloadable.Byte-for-byte identical on every page for talkpython.fm and training.talkpython.fmPasses 100% of the unit tests of the original chameleon project. See compatibility page.Natively supports my chameleon-flask, fastapi-chameleon, and chameleon-partials libraries.Swapping Talk Python Training to chameleon-rs made it 20% fast (end-to-end, not just template rendering)! Calvin #3: Bringing uv and ty together Status: Astral (Sara Sklenka, Oct 13) announced "an experimental integration between uv and ty, available in preview." They ask for feedback, and say "in parallel, we're ...
    Voir plus Voir moins
    34 min
  • #501 A Nod to Sir-Mix-Alot
    Oct 20 2026
    Topics covered in this episode: Nod: pause your Python program and open a notebook at any linePolars 2.0 ships: streaming engine by default, spill-to-disk, and a row-order gotchadjango-cachalot caches your ORM queries and invalidates them for youTowards async transactions in DjangoExtrasJokeWatch on YouTube About the show Sponsored by us! Support our work through: Our courses at Talk PythonConsulting from Six Feet Up Connect with the hostsMichael: Mastodon / BlueSky / X / LinkedInCalvin: Mastodon / BlueSky / X / LinkedInShow: Mastodon / BlueSky / XJoin 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: Nod: pause your Python program and open a notebook at any line Nod (Notebooks-on-Demand) is a JupyterLab extension by Eric Rawn that drops a notebook into a running Python program. Add a notebook() call anywhere, run the program with nod, and execution pauses there with a notebook containing all variables at that point in the call stack. Edits go back to the source file with a button, with cells converted to code and markdown to comments via Jupytext. It answers the classic 'this would be easier in a notebook' debugging moment without copying snippets out to files.Like a breakpoint with a notebook inside: the left panel walks the call stack and notebook state switches with itInstall is pip install nodpy plus nod --install-kernel, then run with nod python -m myfileThe round trip back to source is the differentiator; markdown cells become comments, cells become newlines, and notebooks are disposable since the source file recreates themnodLog() stashes variable values across calls to explore later; the article also pitches notebook() for stepping through AI-generated code line by lineEarly stage: repo from December 2025 with 16 stars and essentially one contributor, so expect rough edges Calvin #2: Polars 2.0 ships: streaming engine by default, spill-to-disk, and a row-order gotcha Polars 2.0 released Oct 6, 2026 (Ritchie Vink). The post says it's "not intended to be a big feature release", but it bundles a few big changes.LazyFrame.collect now defaults to the streaming engine, with large memory and speed gains on most queries.Breaking: streaming doesn't guarantee row order for join, group_by and unpivot. Use maintain_order=True if order matters. This is why it's a major version.Out-of-core (spill-to-disk) is on by default. It spills at about 80% of RAM ("may need tuning") with a 64 GB default disk budget. It covers sort, window functions and many expressions. Joins and group-bys are planned, not shipped.The new native Map dtype (Arrow MapType) replaces the old List(Struct(key, value)) reading. It comes with map.get, map.contains_key, map.len, map.keys and map.values.Stricter by design: errors should surface up front and implicit handling of data mismatches is opt-in. collect_schema() catches schema mismatches without reading data.SQL is now a first-class interface, with join reordering, better common-subplan elimination, and dynamic predicates/bloom filters.Benchmarks are self-run TPC-H/TPC-DS derived numbers against DuckDB 1.5.6 and 2.0 alpha, and DataFusion 54. They are not official TPC results.Polars was fastest on all but one benchmark. At 192 threads its constant overhead hurts small data (SF10 TPC-DS is 1.8x slower), and a fix is hoped for in the next release.Roadmap, not released: out-of-core joins and group-bys, better scaling at high core counts, Polars Cloud, and early GeoPolars work.Upgrade guide: https://docs.pola.rs/releases/upgrade/2/ Michael #3: django-cachalot caches your ORM queries and invalidates them for you django-cachalot is a Django package that caches ORM queries and invalidates them automatically when the underlying data changes. Install it, add one line to INSTALLED_APPS, and read queries run through your cache backend with no code changes. The trick is that it caches whole tables, so any write flushes that table's cached queries, making it a strong fit for read-heavy sites and a poor one for frequently updated tables. It supports Django 4.2 through 6.1 and Python 3.8 to 3.14. ORM caching that normally takes careful engineering drops in with pip install and one settings line, invalidation included.Near-100x on joins: the README reports nearly 100x speedups for initial deployments heavy on select_related and prefetch_related.It caches the entire table, so a hot table with frequent writes invalidates constantly; docs suggest staying under 50 modifications per minute and mixing in cache-machine for hot paths.Setup is two lines, plus caveats: sync clocks across servers sharing one cache, and run a manage.py command after restoring a database outside Django. Calvin #4: Towards async transactions in Django Carlton ...
    Voir plus Voir moins
    38 min
  • #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 ...
    Voir plus Voir moins
    1 h et 8 min
  • #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...
    Voir plus Voir moins
    33 min
  • #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 ...
    Voir plus Voir moins
    33 min
  • #497 Faster than light profiling
    Sep 23 2026
    Topics covered in this episode: Tachyon: A sampling profiler ships in Python 3.15's stdlibPython Workers are now generally available on CloudflareFlet 1.0 - build cross-platform apps in Pythonmarimo-book: Build static books from marimo notebooksExtrasJokeWatch on YouTube Sponsored by Logfire from Pydantic: pythonbytes.fm/logfire 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: 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 Tachyonpy-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 profilersDefaults: 1 kHz, main thread, wall clock, and a -live top-like view for poking at a slow serverOutput 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 markersProfiling 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 childNear-zero overhead for production; guidance is 10-30 second windows on representative load, and free-threaded builds divide the rate by thread countAttach to a running PID, same minor version only; ptrace permissions are the main friction. A 3.14 backport already exists on GitHubCaveat: 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 PlatformNo 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 connectivityFrameworks supported: FastAPI, Django, Flask; AI libs like OpenAI SDK, LangChain, MCPUnderlying platform work formalized as PEP 783 (PyEmscripten), after a year of discussionBottom 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 neededOne codebase targets six platforms: iOS, Android, Windows, macOS, Linux, web150+ built-in UI controls, plus support for custom controls / wrapping Flutter packagesMobile now supports real Python packages: NumPy, pandas, Pillow, cryptographyComes with pytest-based UI testing and an MCP integration for AI coding assistantsMilestone 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], [...
    Voir plus Voir moins
    27 min