<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Bernát Gábor — Python packaging, tox, virtualenv &amp; open source</title><link>https://bernat.tech/</link><description>Engineering notes from Bernát Gábor, PyPA maintainer of tox, virtualenv, pipx, filelock and platformdirs: Python packaging, typing and supply chain security.</description><generator>Hugo 0.167.0</generator><language>en-US</language><lastBuildDate>Fri, 10 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://bernat.tech/index.xml" rel="self" type="application/rss+xml"/><item><title>How turbohtml makes Python HTML work 3-22x faster</title><link>https://bernat.tech/posts/blazing-fast-html-parser/</link><pubDate>Thu, 18 Jun 2026 09:00:00 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/blazing-fast-html-parser/</guid><description>&lt;p&gt;Python&amp;rsquo;s &lt;code&gt;html.escape&lt;/code&gt; can scan one string five times. Moving those loops into C removes the interpreter from the hot&#10;path, which explains part of a 22x result on prose. Most prose contains nothing to escape. turbohtml gets the rest of&#10;the speedup by proving that sixteen bytes need no work, then moving past them in one step.&lt;/p&gt;&#10;&lt;p&gt;I began with a small accelerator for &lt;a href="https://docs.python.org/3/library/html.html#html.escape" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;html.escape&lt;/code&gt;&lt;/a&gt;&#10; and&#10;&lt;a href="https://docs.python.org/3/library/html.html#html.unescape" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;html.unescape&lt;/code&gt;&lt;/a&gt;&#10;. The Python implementation of &lt;code&gt;escape&lt;/code&gt; runs&#10;up to five &lt;code&gt;str.replace&lt;/code&gt; passes. &lt;code&gt;unescape&lt;/code&gt; runs a regular expression and calls back into Python for each match in the&#10;2,231-entry HTML5 entity table. &lt;code&gt;html.parser.HTMLParser&lt;/code&gt; calls &lt;code&gt;unescape&lt;/code&gt; for each text run it encounters, so both&#10;functions sit on hot paths. Interpreter dispatch explains the standard-library gap; its authors made reasonable choices&#10;under different maintenance constraints.&lt;/p&gt;</description><category>python</category><category>c</category><category>performance</category><category>simd</category><category>html</category><category>parser</category><category>tokenizer</category><category>unicode</category><category>turbohtml</category><category>idna</category><category>pgo</category><category>lto</category><category>benchmarking</category></item><item><title>Deterministic Multithreaded Testing in Python with blanket</title><link>https://bernat.tech/posts/blanket-deterministic-threading/</link><pubDate>Thu, 28 May 2026 17:57:48 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/blanket-deterministic-threading/</guid><description>&lt;div class="alert alert-info"&gt;&#10; &lt;p class="alert-title"&gt;&lt;i class="fa-solid fa-circle-info" aria-hidden="true"&gt;&lt;/i&gt; TLDR:&lt;/p&gt;&#10; &lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#why-multithreaded-python-tests-are-flaky"&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/a&gt;&#10;: testing multithreaded code is hard because the OS&#10;scheduler decides which thread runs when, making race conditions all but impossible to reproduce in a test suite.&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#enter-blanket-deterministic-threading-control"&gt;&lt;strong&gt;The solution&lt;/strong&gt;&lt;/a&gt;&#10;: &lt;a href="https://pypi.org/project/blanket/" target="_blank" rel="noopener noreferrer"&gt;blanket&lt;/a&gt;&#10;&#10;wraps real &lt;code&gt;threading&lt;/code&gt; primitives (Lock, Condition, Event, Barrier, Semaphore) and lets your test act as the&#10;scheduler, controlling which thread proceeds at each step.&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#why-now"&gt;&lt;strong&gt;Why now&lt;/strong&gt;&lt;/a&gt;&#10;: free-threaded Python (no &lt;a href="https://docs.python.org/3/glossary.html#term-GIL" target="_blank" rel="noopener noreferrer"&gt;GIL&lt;/a&gt;&#10;) shipped&#10;as an experimental build in 3.13, is&#10;&lt;a href="https://docs.python.org/3.14/whatsnew/3.14.html" target="_blank" rel="noopener noreferrer"&gt;officially supported in 3.14&lt;/a&gt;&#10;, and keeps maturing in&#10;&lt;a href="https://docs.python.org/3.15/whatsnew/3.15.html" target="_blank" rel="noopener noreferrer"&gt;3.15&lt;/a&gt;&#10;. The GIL was hiding thread-safety bugs you did not know you&#10;had; without it, they surface.&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#how-it-works-under-the-hood"&gt;&lt;strong&gt;How it works&lt;/strong&gt;&lt;/a&gt;&#10;: every method call on a blanket primitive becomes a &lt;em&gt;transaction&lt;/em&gt;&#10;that parks at a &lt;em&gt;scheduler block&lt;/em&gt;. Your test unblocks transactions in whatever order you want, making execution 100%&#10;deterministic.&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#concurrency-testing-tools-compared"&gt;&lt;strong&gt;What makes it different&lt;/strong&gt;&lt;/a&gt;&#10;: unlike stateless model checkers&#10;(&lt;a href="https://github.com/tokio-rs/loom" target="_blank" rel="noopener noreferrer"&gt;Loom&lt;/a&gt;&#10;, &lt;a href="https://github.com/awslabs/shuttle" target="_blank" rel="noopener noreferrer"&gt;Shuttle&lt;/a&gt;&#10;,&#10;&lt;a href="https://www.microsoft.com/en-us/research/project/chess-find-and-reproduce-heisenbugs-in-concurrent-programs/" target="_blank" rel="noopener noreferrer"&gt;CHESS&lt;/a&gt;&#10;)&#10;that &lt;em&gt;discover&lt;/em&gt; bugs by exploring interleavings, blanket lets you &lt;em&gt;declare&lt;/em&gt; specific scenarios by hand, useful for&#10;regression tests of known bugs and for full coverage of rare code paths.&lt;/li&gt;&#10;&lt;/ul&gt;&#10; &lt;/div&gt;&lt;p&gt;Most multithreaded Python codebases keep at least one test marked &lt;code&gt;@pytest.mark.flaky(reruns=5)&lt;/code&gt;: the one that fails&#10;once in a thousand because of a race condition you cannot reproduce on demand. The bug is a specific sequence of thread&#10;interactions. You do not get to pick the sequence; the OS scheduler does. You ship the retry and hope.&lt;/p&gt;</description><category>python</category><category>testing</category><category>concurrency</category><category>threading</category><category>free-threading</category><category>blanket</category><category>pycon</category><category>race-condition</category><category>gil</category></item><item><title>PyCon US 2026 Packaging Summit Recap</title><link>https://bernat.tech/posts/pycon-us-2026-packaging-summit-recap/</link><pubDate>Fri, 15 May 2026 23:00:00 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/pycon-us-2026-packaging-summit-recap/</guid><description>&lt;p&gt;The &lt;a href="https://us.pycon.org/2026/events/packaging-summit/" target="_blank" rel="noopener noreferrer"&gt;PyCon US 2026 Packaging Summit&lt;/a&gt;&#10; ran Friday May 15, 2026, from&#10;1:45 PM to 5:45 PM in Room 201A of the Long Beach Convention Center. Three talks, nine lightning talks, six roundtable&#10;discussions. Organized by &lt;a href="https://pradyunsg.me/" target="_blank" rel="noopener noreferrer"&gt;Pradyun Gedam&lt;/a&gt;&#10;, &lt;a href="https://github.com/CAM-Gerlach" target="_blank" rel="noopener noreferrer"&gt;C.A.M. Gerlach&lt;/a&gt;&#10;, and&#10;&lt;a href="https://github.com/jezdez" target="_blank" rel="noopener noreferrer"&gt;Jannis Leidel&lt;/a&gt;&#10;. This recap is for anyone who could not be in the room.&lt;/p&gt;&#10;&lt;div class="alert alert-info"&gt;&#10; &lt;p class="alert-title"&gt;&lt;i class="fa-solid fa-circle-info" aria-hidden="true"&gt;&lt;/i&gt; TLDR:&lt;/p&gt;&#10; &lt;ul&gt;&#10;&lt;li&gt;Emma Smith&amp;rsquo;s revised &lt;a href="https://peps.python.org/pep-0777/" target="_blank" rel="noopener noreferrer"&gt;PEP 777 (Wheel 2.0)&lt;/a&gt;&#10; is a minimal change with sub-PEPs&#10;layered on top; the first sub-PEP proposes Zstandard compression for ~25% smaller wheels.&lt;/li&gt;&#10;&lt;li&gt;Mike Fiedler brought three PyPI abuse vectors (persistent state, open-ended releases, PyPI as a CDN), framed by 3×&#10;growth against 1× resources (~24,000 new packages per month, up from ~8,000) and a single full-time PyPI safety and&#10;security engineer.&lt;/li&gt;&#10;&lt;li&gt;Mahe Iram Khan argued conda and pip are two parallel ecosystems, not two competing tools.&lt;/li&gt;&#10;&lt;li&gt;Lightning talks: &lt;a href="https://peps.python.org/pep-0772/" target="_blank" rel="noopener noreferrer"&gt;PEP 772 Packaging Council&lt;/a&gt;&#10; approved (Barry Warsaw), mobile&#10;wheel pipeline live (Malcolm Smith), Coherent + Compile-to-Flit (Jason Coombs), wheel variants for AI accelerators&#10;and shared malware scanning (Joongi Kim), conda-pypi (Daniel Holth), Nebi (Dharhas Pothina).&lt;/li&gt;&#10;&lt;li&gt;Roundtables: &lt;a href="https://peps.python.org/pep-0803/" target="_blank" rel="noopener noreferrer"&gt;PEP 803 abi3t&lt;/a&gt;&#10;, Wheel 2.0 hardening, cross-platform builds, CVE&#10;propagation, and &lt;a href="https://github.com/notatallshaw/nab" target="_blank" rel="noopener noreferrer"&gt;nab&lt;/a&gt;&#10; (Damian Shaw&amp;rsquo;s pure-Python resolver aimed at pip&#10;swap-in).&lt;/li&gt;&#10;&lt;li&gt;Involved in Python packaging? Consider running for the Packaging Council this fall or becoming a voting&#10;&lt;a href="https://www.python.org/psf/membership/" target="_blank" rel="noopener noreferrer"&gt;PSF member&lt;/a&gt;&#10; to nominate and vote.&lt;/li&gt;&#10;&lt;/ul&gt;&#10; &lt;/div&gt;&lt;p&gt;For background, I list the packaging-topic PEPs resolved in the year leading up to the summit (January 2025 through May&#10;2026), newest first.&lt;/p&gt;</description><category>python</category><category>pycon</category><category>pycon-us</category><category>packaging-summit</category><category>packaging</category><category>pypi</category><category>wheel</category><category>pep-777</category><category>pep-694</category><category>pep-772</category><category>pep-817</category><category>pep-825</category><category>pep-803</category><category>conda</category><category>trusted-publishing</category><category>supply-chain</category><category>mobile</category><category>beeware</category><category>wheel-variants</category></item><item><title>PyCon US 2026 Typing Summit Recap</title><link>https://bernat.tech/posts/pycon-us-2026-typing-summit-recap/</link><pubDate>Thu, 14 May 2026 23:30:00 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/pycon-us-2026-typing-summit-recap/</guid><description>&lt;p&gt;The &lt;a href="https://us.pycon.org/2026/events/typing-summit/" target="_blank" rel="noopener noreferrer"&gt;PyCon US 2026 Typing Summit&lt;/a&gt;&#10; ran Thursday May 14, 2026, from 1 PM&#10;to 5 PM in Room 201A of the Long Beach Convention Center, the day before the main conference started. Eight talks plus a&#10;Typing Council Q&amp;amp;A, single track. This recap is for anyone who could not be in the room.&lt;/p&gt;&#10;&lt;div class="alert alert-info"&gt;&#10; &lt;p class="alert-title"&gt;&lt;i class="fa-solid fa-circle-info" aria-hidden="true"&gt;&lt;/i&gt; TLDR:&lt;/p&gt;&#10; &lt;ul&gt;&#10;&lt;li&gt;Guido van Rossum argued that &lt;a href="https://peps.python.org/pep-0484/" target="_blank" rel="noopener noreferrer"&gt;PEP 484&lt;/a&gt;&#10;&amp;rsquo;s no-new-syntax rule is already broken in&#10;practice and that the field should weigh user pain over power features, citing the&#10;&lt;a href="https://engineering.fb.com/2025/12/22/developer-tools/python-typing-survey-2025-code-quality-flexibility-typing-adoption/" target="_blank" rel="noopener noreferrer"&gt;2025 Python Typing Survey&lt;/a&gt;&#10;.&lt;/li&gt;&#10;&lt;li&gt;Jelle Zijlstra proposed adding intersection and restricted-negation types to the typing spec, with an inhabitation&#10;check as the load-bearing new rule.&lt;/li&gt;&#10;&lt;li&gt;Michael Sullivan presented &lt;a href="https://peps.python.org/pep-0827/" target="_blank" rel="noopener noreferrer"&gt;PEP 827&lt;/a&gt;&#10; (Vercel) for type manipulation, modelled on&#10;TypeScript&amp;rsquo;s conditional and mapped types.&lt;/li&gt;&#10;&lt;li&gt;Douglas Creager showed how &lt;code&gt;ty&lt;/code&gt; represents generic-call constraints internally with ternary decision diagrams, and a&#10;third solver strategy that fixes a 9-line &lt;code&gt;partial(choose, None)&lt;/code&gt; example every production checker today gets wrong.&lt;/li&gt;&#10;&lt;li&gt;Conner Nilsen presented a Pyrefly experiment with AI coding agents: type checking moves success on well-typed Meta&#10;code from 79.6% to 83.9% with 21% fewer steps; no measurable help on lightly-typed SWE-bench Verified.&lt;/li&gt;&#10;&lt;li&gt;Avik Chaudhuri demoed tensor-shape types in Pyrefly, blocked in practice by&#10;&lt;a href="https://peps.python.org/pep-0695/" target="_blank" rel="noopener noreferrer"&gt;PEP 695&lt;/a&gt;&#10;&amp;rsquo;s eager evaluation of type parameters.&lt;/li&gt;&#10;&lt;li&gt;Jia Chen presented a Lean 4 formalization (Featherweight Python) with mechanized soundness and decidability proofs;&#10;AI assistants turned what used to take years into weeks.&lt;/li&gt;&#10;&lt;li&gt;The Typing Council panel (Carl Meyer, Jelle Zijlstra, Rebecca Chen on stage) opened the floor to attendee questions&#10;on governance, error-code consistency, metaprogramming, and the spec direction.&lt;/li&gt;&#10;&lt;/ul&gt;&#10; &lt;/div&gt;&lt;h2 id="experiments-with-ai-agents-and-pyrefly-type-errors--conner-nilsen"&gt;&#10; Experiments with AI agents and Pyrefly type errors — Conner Nilsen&#10; &lt;a class="heading-link" href="#experiments-with-ai-agents-and-pyrefly-type-errors--conner-nilsen"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;figure&gt;&#10; &lt;img src="https://bernat.tech/posts/pycon-us-2026-typing-summit-recap/conner-nilsen-pyrefly-ai-experiments.webp" alt="Conner Nilsen Findings slide on providing feedback to the agent at higher frequencies"&#10; srcset="https://bernat.tech/posts/pycon-us-2026-typing-summit-recap/conner-nilsen-pyrefly-ai-experiments_hu_a4cff857630366fb.webp 500w, https://bernat.tech/posts/pycon-us-2026-typing-summit-recap/conner-nilsen-pyrefly-ai-experiments_hu_1134013956dc65ba.webp 800w, https://bernat.tech/posts/pycon-us-2026-typing-summit-recap/conner-nilsen-pyrefly-ai-experiments.webp 1024w" sizes="min(1024px, 100vw)"&#10; width="1024" height="768"&#10; loading="lazy" decoding="async"&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;Conner (Meta, &lt;a href="https://pyrefly.org/" target="_blank" rel="noopener noreferrer"&gt;Pyrefly&lt;/a&gt;&#10; team) presented two questions: (1) does giving an AI coding agent a type&#10;checker help it finish tasks, and (2) does it prevent the agent from re-introducing old bugs while fixing new ones? His&#10;team ran two benchmarks with and without type-checker feedback and tracked three metrics: success rate, number of steps&#10;to completion, and wall-clock duration.&lt;/p&gt;</description><category>python</category><category>pycon</category><category>pycon-us</category><category>typing-summit</category><category>typing</category><category>type-hints</category><category>pyrefly</category><category>ty</category><category>astral</category><category>openai</category><category>meta</category><category>vercel</category><category>pep-827</category><category>intersection-types</category><category>constraint-sets</category><category>lean</category><category>tensor-types</category><category>pytorch</category><category>typing-council</category><category>guido</category></item><item><title>PyTexas 2026 Recap</title><link>https://bernat.tech/posts/pytexas-2026-recap/</link><pubDate>Sun, 19 Apr 2026 22:00:00 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/pytexas-2026-recap/</guid><description>&lt;p&gt;&lt;a href="https://www.pytexas.org/" target="_blank" rel="noopener noreferrer"&gt;PyTexas&lt;/a&gt;&#10; is the annual Python conference held in Austin, Texas. The 2026 edition ran April&#10;17–19 at the &lt;a href="https://library.austintexas.gov/central-library" target="_blank" rel="noopener noreferrer"&gt;Austin Central Library&lt;/a&gt;&#10; in downtown Austin.&lt;/p&gt;&#10;&lt;div class="alert alert-info"&gt;&#10; &lt;p class="alert-title"&gt;&lt;i class="fa-solid fa-circle-info" aria-hidden="true"&gt;&lt;/i&gt; TLDR:&lt;/p&gt;&#10; &lt;p&gt;PyTexas 2026 ran April 17–19 in Austin. Friday was tutorials, Saturday and Sunday were talks with two keynotes and two&#10;lightning-talk blocks. A few themes kept coming back across unrelated talks:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Design deliberately.&lt;/strong&gt; A thread across both keynotes. Hynek Schlawack: the domain model is &lt;em&gt;&amp;ldquo;the precious&amp;rdquo;&lt;/em&gt; -&#10;design it first, translate at the edges. Dawn Wages: ownership over your stack as one of her three pillars for model&#10;and career specialization.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Agents should write code, not decide what to write.&lt;/strong&gt; Peter Sobot&amp;rsquo;s Seven Stages of AI Grief ended on that line.&#10;Al Sweigart argued &amp;ldquo;agentic engineering&amp;rdquo; is vibe coding with better marketing, and that almost-right is worse than&#10;wrong. Maria Silvia Mielniczuk&amp;rsquo;s MCP talk built the same idea into an architecture: models suggest, only the server&#10;executes. Adam Gordon Bell&amp;rsquo;s running coach split deterministic work (plain Python) from interpretation (LLM). The&#10;Sunday opener framed it: when AI ships a bad PR, fix the process, not the model.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Code quality is an input to AI productivity.&lt;/strong&gt; Miguel Vargas&amp;rsquo;s framing: AI agents produce cleaner, safer code in&#10;codebases that are already clean, safe, and typed, so Ruff, ty, and uv matter more now.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;The supply chain is still the attack surface.&lt;/strong&gt; Christopher Ariza on why &lt;code&gt;pip install&lt;/code&gt; still runs arbitrary code,&#10;with &lt;code&gt;.pth&lt;/code&gt; files, &lt;code&gt;sitecustomize.py&lt;/code&gt;, and &lt;code&gt;setup.py&lt;/code&gt; as the specific places to pay attention.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;CPython itself is getting faster.&lt;/strong&gt; Jacob Coffee on &lt;a href="https://peps.python.org/pep-0810/" target="_blank" rel="noopener noreferrer"&gt;PEP 810&lt;/a&gt;&#10; lazy imports for&#10;startup wins; Charlie Lin on the free-threaded build and what it takes to make an extension module safe under it.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;This post details the takeaways from each talk I attended, in schedule order.&lt;/p&gt;&#10; &lt;/div&gt;</description><category>python</category><category>pytexas</category><category>conference</category><category>austin</category><category>ai</category><category>llm</category><category>mcp</category><category>keynote</category><category>hynek</category><category>packaging</category><category>supply-chain</category><category>pep-810</category><category>free-threading</category><category>ruff</category><category>uv</category><category>ty</category><category>type-checking</category><category>observability</category><category>cli</category></item><item><title>Defense in Depth: A Practical Guide to Python Supply Chain Security</title><link>https://bernat.tech/posts/securing-python-supply-chain/</link><pubDate>Tue, 10 Mar 2026 00:00:00 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/securing-python-supply-chain/</guid><description>&lt;div class="alert alert-info"&gt;&#10; &lt;p class="alert-title"&gt;&lt;i class="fa-solid fa-circle-info" aria-hidden="true"&gt;&lt;/i&gt; TLDR:&lt;/p&gt;&#10; &lt;p&gt;Layer your defenses and do not trust any single control. Use Ruff with security rules to catch bugs in your code&#10;before they ship. Pin all your dependencies with cryptographic hashes using &lt;code&gt;uv lock&lt;/code&gt; or&#10;&lt;code&gt;uv pip compile --generate-hashes&lt;/code&gt; so nobody can swap out packages on you. Run&#10;&lt;a href="https://github.com/pypa/pip-audit" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;pip-audit&lt;/code&gt;&lt;/a&gt;&#10; in CI to catch known CVEs before they hit production. Generate SBOMs&#10;with CycloneDX so when the next Ultralytics-style compromise drops, you can answer &amp;ldquo;are we affected?&amp;rdquo; in minutes&#10;instead of days.&lt;/p&gt;&#10;&lt;p&gt;If you are publishing packages, ditch the long-lived API tokens and switch to Trusted Publishing with OIDC. This&#10;generates attestations automatically via Sigstore, linking your packages back to source repos. Organizations running&#10;internal mirrors can add a 7-day delay to let the community be your canary - but only if you have the infrastructure&#10;to maintain it.&lt;/p&gt;&#10;&lt;p&gt;Nothing here is perfect. Hash pinning stops tampering but will not save you from a malicious package you installed on&#10;day one. Scanning finds known CVEs but misses zero-days. Attestations prove where code came from, not whether it is&#10;safe. That is why you layer them - when one control fails, the others catch it. Start with linting and pinning for&#10;quick wins, add scanning and SBOMs next, then level up to advanced stuff as you mature.&lt;/p&gt;&#10; &lt;/div&gt;</description><category>python</category><category>security</category><category>dependencies</category><category>supply-chain</category><category>sbom</category><category>pypi</category><category>pip</category></item><item><title>Version numbers: how to use them?</title><link>https://bernat.tech/posts/version-numbers/</link><pubDate>Sat, 16 May 2020 14:15:00 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/version-numbers/</guid><description>&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" target="_blank" rel="noopener noreferrer"&gt;DRY principle&lt;/a&gt;&#10; (an acronym for don&amp;rsquo;t repeat yourself)&#10;encourages software engineers to abstract code into a separate component and reuse it rather than write it over and over&#10;again. If this happens across the system, the best practice is to put it inside a package that lives on its own (a&#10;library) and then pull it in from the applications when required.&lt;/p&gt;&#10;&lt;p&gt;As most of us can&amp;rsquo;t think of every feature that the library might offer or what bugs it might contain, these packages&#10;tend to evolve. Therefore, we need some mechanism to encode these evolutions of the library, and most commonly, this is&#10;a version number.&lt;/p&gt;</description><category>python</category><category>version</category><category>semver</category><category>calver</category><category>0ver</category></item><item><title>Python packaging - Growing Pains</title><link>https://bernat.tech/posts/growing-pain/</link><pubDate>Thu, 07 Feb 2019 13:41:03 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/growing-pain/</guid><description>&lt;p&gt;In my previous two posts, I&amp;rsquo;ve gone over &lt;a href="https://bernat.tech/posts/pep-517-and-python-packaging/"&gt;what package types python has&lt;/a&gt;&#10;, and&#10;&lt;a href="https://bernat.tech/posts/pep-517-518/"&gt;how the package building works&lt;/a&gt;&#10;, especially with the introduction of the PEP-517/518. Although the&#10;changes were meant to make things more robust, we did run into a few issues while implementing and releasing them. The&#10;following are a few of those, serving as lessons learned for all of us and presenting some interesting problems to solve&#10;in the future.&lt;/p&gt;</description><category>python</category><category>packaging</category><category>pip</category><category>setuptools</category><category>pep517</category><category>pep518</category></item><item><title>Python packaging - Past, Present, Future</title><link>https://bernat.tech/posts/pep-517-518/</link><pubDate>Thu, 07 Feb 2019 13:40:59 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/pep-517-518/</guid><description>&lt;p&gt;Have you ever wondered what happens when you run pip install? This post gives a detailed overview of the steps involved&#10;in the past, and how it all changes with the adoption of PEP-517 and PEP-518.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://bernat.tech/posts/pep-517-and-python-packaging/"&gt;In my previous post&lt;/a&gt;&#10; I&amp;rsquo;ve described how it&amp;rsquo;s possible to install three types of&#10;content: source tree, source distribution, and wheels. Only the last two types are uploaded to PyPI, the central Python&#10;repository. However, one could get its hands on a source tree (by feeding, for example, a git protocol for pip). The&#10;advantage of wheels over the others is that it does not require any build operation to happen on the user machine; it&amp;rsquo;s&#10;a download and extract.&lt;/p&gt;</description><category>python</category><category>pip</category><category>install</category><category>packaging</category><category>setuptools</category><category>pep517</category><category>pep518</category></item><item><title>The state of Python Packaging</title><link>https://bernat.tech/posts/pep-517-and-python-packaging/</link><pubDate>Thu, 07 Feb 2019 13:40:54 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/pep-517-and-python-packaging/</guid><description>&lt;p&gt;pip 19.0 has been released on 22nd January 2019. On the feature list, most notably, it now supports PEP-517, which by&#10;default is turned &lt;strong&gt;on&lt;/strong&gt; when that the project has a &lt;code&gt;pyproject.toml&lt;/code&gt; at the root folder. The PEP in question has been&#10;created in 2015 and accepted in 2017. Even though it took a while until pip implemented it, the release and the issues&#10;that followed confirmed that many people are not familiar with it. Read on if you want a picture of how the Python&#10;packaging ecosystem evolved today and where we hope to see it down the line. The introduction of this python enhancement&#10;proposal may cause some discomfort, but we will benefit from it in the long term.&lt;/p&gt;</description><category>python</category><category>packaging</category><category>pip</category><category>setuptools</category><category>pep517</category><category>pep518</category><category>wheel</category><category>sdist</category></item><item><title>The state of type hints in Python</title><link>https://bernat.tech/posts/the-state-of-type-hints-in-python/</link><pubDate>Wed, 30 May 2018 09:51:55 +0000</pubDate><dc:creator>Bernát Gábor</dc:creator><guid>https://bernat.tech/posts/the-state-of-type-hints-in-python/</guid><description>&lt;p&gt;One of the main selling points for Python is that it is dynamically-typed. There is no plan to change this.&#10;Nevertheless, in September 2014 &lt;a href="https://twitter.com/gvanrossum" target="_blank" rel="noopener noreferrer"&gt;Guido van Rossum&lt;/a&gt;&#10; (Python&#10;&lt;a href="https://en.wikipedia.org/wiki/Benevolent_dictator_for_life" target="_blank" rel="noopener noreferrer"&gt;BDFL&lt;/a&gt;&#10;) created a python enhancement proposal&#10;(&lt;a href="https://peps.python.org/pep-0484/" target="_blank" rel="noopener noreferrer"&gt;PEP-484&lt;/a&gt;&#10;) to add type hints to Python. It has been released for general usage a&#10;year later, in September 2015, as part of Python &lt;code&gt;3.5.0&lt;/code&gt;.&#10;&lt;a href="https://python-history.blogspot.com/2009/01/brief-timeline-of-python.html" target="_blank" rel="noopener noreferrer"&gt;Twenty-five years into its existence&lt;/a&gt;&#10; now&#10;there was a standard way to add type information to Python code. In this blog post, I&amp;rsquo;ll explore how the system matured,&#10;how you can use it, and what&amp;rsquo;s next for type hints.&lt;/p&gt;</description><category>mypy</category><category>python</category><category>types</category><category>type-hint</category></item></channel></rss>