Zahlbloghttps://zahlman.github.io/Ramblings of a veteran Pythonista with a passion for refactoring and education.enContents © 2022-2026 <a href="proxy.php?url=mailto:[email protected]">Karl Knechtel</a> Wed, 25 Feb 2026 22:08:14 GMTNikola (getnikola.com)http://blogs.law.harvard.edu/tech/rss- Meta-automationhttps://zahlman.github.io/posts/meta-automation/Karl Knechtel<div><p>One of the really fun things about <a href="proxy.php?url=https://zahlman.github.io/posts/leaning-in-to-my-ux">switching to Linux</a> is realizing just how much you can accomplish with a few lines of Bash. Especially when those lines are taking advantage of, not just built-in programs, but other things you made before.</p>
<p>Today I <a href="proxy.php?url=https://github.com/zahlman/func2cmd/">published</a> a couple of tiny tools I use to make my life easier, and I'd like to talk about them a little bit.</p>
<p><a href="proxy.php?url=https://zahlman.github.io/posts/meta-automation/">Read more…</a> (9 min remaining to read)</p></div>bashdev-philosophylinuxpythonhttps://zahlman.github.io/posts/meta-automation/Wed, 25 Feb 2026 05:00:00 GMT
- Python Packaging 外伝1: Oxidation and Radiation - The Rise of uv in 2025https://zahlman.github.io/posts/oxidation/Karl Knechtel<div><p>Today I'm offering a sort of <a href="proxy.php?url=https://en.wikipedia.org/wiki/Spinoff_%28media%29#Sidequels">"side story"</a> to my main series on Python packaging. The main thrust of the series has been that everything is broken or historically has been broken; but I've also been trying to fight some common misconceptions and defend some things that people don't seem to like but which are actually quite reasonable in context.</p>
<p>But I've been doing this in the shadow of <code>uv</code> existing, and <code>uv</code>'s <a href="proxy.php?url=https://www.star-history.com/#astral-sh/uv&type=date&legend=top-left">momentum has been unstoppable this year</a>. Of course there were many adopters in 2024 as well, but we're now seeing more and more evidence in PyPI stats, surveys, CI pipelines etc. that <a href="proxy.php?url=https://old.reddit.com/r/Python/comments/1isv37n/is_uv_package_manager_taking_over/">people are switching</a> away from <code>pip</code> (and other tools) to <code>uv</code>.</p>
<p>Which is unsurprising, given how positive the coverage has been overall. There have been <a href="proxy.php?url=https://hn.algolia.com/?dateRange=pastYear&page=0&prefix=false&query=uv&sort=byPopularity&type=story">many</a> popular posts about it on Hacker News this year (I wouldn't mind adding to the pile!) and everyone is touting its features and praising their experience with it.</p>
<p>So before the year is out, I really wanted to write down some thoughts about <code>uv</code>'s success so far and the impact it's had on me — which as it turns out is mostly <em>not</em> about actually using it. This will mostly be gathering things that I've already said repeatedly in the aforementioned threads, but I think there's value to that.</p>
<p><a href="proxy.php?url=https://zahlman.github.io/posts/oxidation/">Read more…</a> (12 min remaining to read)</p></div>designpythonuvhttps://zahlman.github.io/posts/oxidation/Wed, 31 Dec 2025 05:00:00 GMT
- Python packaging: Why we can't have nice things - Part 3: Premature Compilationhttps://zahlman.github.io/posts/python-packaging-3/Karl Knechtel<div><p>Pip 25.0 <a href="proxy.php?url=https://discuss.python.org/t/_/78392">has been out</a> for <a href="proxy.php?url=https://github.com/pypa/pip/releases/tag/25.0">a bit over a month now</a>; and we now also have an <a href="proxy.php?url=https://ichard26.github.io/blog/2025/01/whats-new-in-pip-25.0/">official blog post</a> about the release, as well as a 25.0.1 patch for a regression.</p>
<p>Pip 25.0 has what I consider a very serious security vulnerability. In the Python ecosystem, it's normal and expected that third-party packages provide their own, arbitrary "setup" code for installation (for example, to run C compilers in project-specific ways, when the code uses a C extension). But Pip will run such code <em>in many more situations than you might naively expect</em>. I think it's obvious that running arbitrary code <em>when you aren't expecting it and prepared for it</em> is a much bigger problem. The user should have a chance to decide whether to trust the code, first.</p>
<p>I believe that warnings are more important than baiting people to read the post, so here's the PSA up front:</p>
<ol>
<li>
<p><strong>Never use Pip to download, test, "dry-run" etc. an untrusted source distribution (sdist).</strong> <a href="proxy.php?url=https://github.com/pypa/pip/issues/1884">It will try to build the package</a>, <strong>potentially running arbitrary code</strong> (as building an sdist always entails). Instead, use the <a href="proxy.php?url=https://pypi.org">PyPI website</a> directly, or the <a href="proxy.php?url=https://docs.pypi.org/api/json/">API</a> it provides.</p>
</li>
<li>
<p><strong>Never use <code>sudo</code> to run Pip</strong> (nor run it with administrative privileges on Windows). Aside from the potential problems caused by conflicting with the system package manager, Pip <a href="proxy.php?url=https://github.com/pypa/pip/issues/11034"><strong>will not drop privileges</strong></a> when it runs as root and attempts to build an sdist - which again, <strong>potentially runs arbitrary code</strong>.</p>
</li>
<li>
<p>If you expect wheels to be available for the packages you want to install with Pip, <strong>strongly consider adding <code>--only-binary=:all:</code> to the Pip command</strong> to ensure that only wheels are used. If you really need to use sdists, it's wise to inspect them first, which by definition isn't possible with a fully automated installation.</p>
</li>
<li>
<p>If you release Python packages, <a href="proxy.php?url=https://pradyunsg.me/blog/2022/12/31/wheels-are-faster-pure-python/">please try to provide wheels for them</a>, even if - no, <em>especially</em> if your package includes only Python code and doesn't require explicitly "compiling" anything. An sdist is <em>much</em> slower to install than a wheel even in these cases, and making a wheel available allows your users to demand wheels from Pip - raising the overall baseline for trust and safety in the Python ecosystem.</p>
</li>
</ol>
<p>Okay, I did clickbait a bit. This security issue <em>isn't</em> some new discovery. In fact, it has plagued Pip <em>for its entire history</em>.</p>
<p>Please enjoy my detailed analysis below.</p>
<p><a href="proxy.php?url=https://zahlman.github.io/posts/python-packaging-3/">Read more…</a> (33 min remaining to read)</p></div>pippythonsecuritysetuptoolshttps://zahlman.github.io/posts/python-packaging-3/Fri, 28 Feb 2025 05:00:00 GMT
- Leaning IN to my U/Xhttps://zahlman.github.io/posts/leaning-in-to-my-ux/Karl Knechtel<div><div class="code"><pre class="code literal-block">$<span class="w"> </span>stat<span class="w"> </span>/<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>Birth<span class="w"> </span><span class="p">|</span><span class="w"> </span>cut<span class="w"> </span>-d<span class="w"> </span><span class="s1">' '</span><span class="w"> </span>-f<span class="w"> </span><span class="m">3</span>
<span class="m">2022</span>-01-24
</pre></div>
<p>Today (although this won't go live until the 25th in my time zone) is three years since the day I finally kicked Windows to the curb and installed Linux on my home desktop. I'd used Linux before, but all my life I'd had a habit of just using whatever OS was provided to me, without really giving it much thought.</p>
<p>In late 2021, Windows Update told me - entirely unprompted - that my system didn't meet minimum specs to run Windows 11. (Perhaps it would now - I understand that the declared requirements have been relaxed, even if nothing has been optimized or stripped down - but I don't care to check. I'm also told that people still on Windows 10 are under increasing pressure to switch, even though they're <a href="proxy.php?url=https://www.pcworld.com/article/2508289/windows-11-market-share-grows-but-windows-10-still-twice-as-popular.html">still comfortably in the majority</a> - unless something has radically changed in the last few months.)</p>
<p>I found this impolite - as I hadn't asked, and didn't consider anything wrong or inadequate about my computer - and a bit absurd (whatever they're offering now that requires more computing power, I'm not interested; especially not if it's anything to do with Cortana). So I took that as my queue to switch. I bought a new SSD (figuring I would need the space anyway) and attempted to set up a dual boot - GRUB never worked properly for me, but I could still use the BIOS screen to boot Windows from the old SSD.</p>
<p>And I never looked back.</p>
<p>Today, I'd like to relate a few anecdotes about that experience.</p>
<p><a href="proxy.php?url=https://zahlman.github.io/posts/leaning-in-to-my-ux/">Read more…</a> (10 min remaining to read)</p></div>linuxpersonalhttps://zahlman.github.io/posts/leaning-in-to-my-ux/Fri, 24 Jan 2025 05:00:00 GMT
- A Brief Annotationhttps://zahlman.github.io/posts/a-brief-annotation/Karl Knechtel<p>I've been quite busy working on both the next article in my <a href="proxy.php?url=https://zahlman.github.io/tags-and-series/series-python-packaging">packaging series</a> and on the overall appearance of the blog (I wasn't able to keep that confined to the weekend, apparently).</p>
<p>So, today, just a quick note, on the occasion of the 4th anniversary of the creation of <a href="proxy.php?url=https://peps.python.org/pep-0649/">PEP 649</a> "Deferred Evaluation Of Annotations Using Descriptors".</p>
<p>Yes, that's a mouthful, but in short: starting in Python 3.14, if you use annotations, you'll be able to defer the evaluation of the annotation code. (The feature <a href="proxy.php?url=https://discuss.python.org/t/_/21331/43">was supposed to be added for 3.13, but didn't make it in</a>.) That means you don't have to rely on strings for forward references in your type annotations, but you can still make full use of annotations at runtime (you'll have a proper object for the annotation itself, rather than just a string). Thank you to core Python developer Mr. Larry Hastings for putting a tremendous amount of effort into refining this proposal.</p>
<p>Now, I don't personally use type annotations very much - I don't use a type checker at all; I only write annotations as a form of documentation. But as it happened, <a href="proxy.php?url=https://zahlman.github.io/tags-and-series/series-python-discourse-ban">when I was new to the Python Discourse forum</a>, I came across Mr. Hastings' post, puzzling over the best way to name what will soon become the <code>__annotate__</code> attribute of annotated objects.</p>
<p>The name <code>__annotate__</code> <a href="proxy.php?url=https://discuss.python.org/t/_/25672/4">was my suggestion</a>.</p>
<p>I was not credited in the PEP, and I <a href="proxy.php?url=https://discuss.python.org/t/_/25672/61">was ignored</a> when I tried to point this out. So it falls to me to draw attention to my contribution.</p>
<p>This is all very niche stuff, of course - but I'm happy to have been able to leave this mark on the Python language itself, as opposed to just making useful things with it.</p>pythonhttps://zahlman.github.io/posts/a-brief-annotation/Sat, 11 Jan 2025 05:00:00 GMT
- Python Packaging: Why we can't have nice things - Part 2: Stupid Pipx Trickshttps://zahlman.github.io/posts/python-packaging-2/Karl Knechtel<div><p>Pip has a lot of problems (that I'll be discussing in future posts in this series), but the good news is that you don't have to resort to heavyweight third-party tools to improve your experience with Python packaging. <a href="proxy.php?url=https://pipx.pypa.io/stable/">Pipx</a> (now <a href="proxy.php?url=https://packaging.python.org/en/latest/key_projects/#pipx">under</a> the <a href="proxy.php?url=https://www.pypa.io/en/latest/">Python Packaging Authority (PyPA)</a> umbrella) is a focused wrapper around Pip that handles the major pain points without trying to take over your entire workflow.</p>
<p>In this post I'll talk about Pipx's major use cases, its limitations, and how to get more mileage out of it with a few simple tweaks.</p>
<p><a href="proxy.php?url=https://zahlman.github.io/posts/python-packaging-2/">Read more…</a> (9 min remaining to read)</p></div>pippipxpythonhttps://zahlman.github.io/posts/python-packaging-2/Tue, 07 Jan 2025 05:00:00 GMT
- New year, new bloghttps://zahlman.github.io/posts/new-year-new-blog/Karl Knechtel<div><p>You're not imagining things - the blog has a whole new look, in large part as a result of switching to the <a href="proxy.php?url=https://getnikola.com">Nikola</a> site generator.</p>
<p><a href="proxy.php?url=https://zahlman.github.io/posts/new-year-new-blog/">Read more…</a> (2 min remaining to read)</p></div>jekyllmetanikolapythonhttps://zahlman.github.io/posts/new-year-new-blog/Wed, 01 Jan 2025 05:00:00 GMT
- fixup! added list - The rest of the TODOwlhttps://zahlman.github.io/posts/todo-list-2/Karl Knechtel<div><p>Happy new year to all.</p>
<p>Today's post is about a folder on my desktop named <code>dev</code>. It's where I've kept (for many years, well into my Windows-using days, even into the era when I used SVN rather than Git) all my working copies for my own projects (and forks of others'), mostly Python code of course. (I'm not sure how I organized things at the time, but there are projects in there dating back to 2006.)</p>
<p><a href="proxy.php?url=https://zahlman.github.io/posts/todo-list-2/">Read more…</a> (20 min remaining to read)</p></div>metapersonalpythonhttps://zahlman.github.io/posts/todo-list-2/Tue, 31 Dec 2024 05:00:00 GMT
- Python packaging: Why we can't have nice things - Part 1: The Old Refrainhttps://zahlman.github.io/posts/python-packaging-1/Karl Knechtel<div><p>This post is a start of a series I've planned about how packaging currently works in Python, what's wrong with it, and how to cope with the problems. But before I get into the meat of it, I want to talk about common complaints that <em>don't</em> resonate with me.</p>
<p><a href="proxy.php?url=https://zahlman.github.io/posts/python-packaging-1/">Read more…</a> (21 min remaining to read)</p></div>pippythonvirtual-environmentshttps://zahlman.github.io/posts/python-packaging-1/Tue, 24 Dec 2024 05:00:00 GMT
- # TODO: finish todo listhttps://zahlman.github.io/posts/todo-finish-todo-list/Karl Knechtel<div><p>This is a difficult post to write, largely because of the self-critique involved. Which is part of why I've been putting it off. For months, if I'm honest with myself.</p>
<p>But putting it off has only made it harder to write. I also seem to have reached a point where it psychologically feels impossible to publish anything else here first. So, I'm finally forcing myself to write it now - during the holiday season, to prove to myself that I can.</p>
<p>It's no secret that the history of this blog so far has been dominantly one of false starts. Please allow me a moment to explain how that came to be.</p>
<p><a href="proxy.php?url=https://zahlman.github.io/posts/todo-finish-todo-list/">Read more…</a> (7 min remaining to read)</p></div>metapersonalhttps://zahlman.github.io/posts/todo-finish-todo-list/Fri, 20 Dec 2024 05:00:00 GMT