Over on Wandering Thoughts, Chris writes about some fileserver management tools being fairly unchanged over time by changes to the environment. There is a Python 2 to 3 conversion, and some changes when the disks being managed are no longer on iSCSI, “but in practice a lot of code really has carried on basically as-is.”
This is completely different than my experience with async/await in Python. Async was new, so the library I used with it was in 0.x, and in 1.0, the authors inverted the entire control structure. Instead of being able to create an AWS client deep in the stack and return it upwards, clients could only be used as context managers. It was quite a nasty surprise.
To allow testing for free, my code dynamically instantiated a module to “manage storage,” and whether that was AWS or in-memory was an implementation detail. Suddenly, one of the clients couldn’t write
self.client = c; return anymore. The top-level had to know about the change. Other storage clients would have to know about the change, to become context managers themselves, for no reason.
I held onto the 0.x version for a while, until the Python core team felt like “explicit event loop” was a mistake big enough that everyone’s code had to be broken.
Async had been hard to write in the first place, because so much example code out there was for the
asyncio module’s decorators, which had preceded the actual async/await syntax. What the difference between tasks and coroutines even was, and why one should choose one over the other, was never clear. Why an explicit
loop parameter should exist was especially unclear, but it was “best practice” to include it everywhere, so everyone did. Then Python set it on fire.
(I never liked the Python packaging story, and pipenv didn’t solve it. To pipenv, every Python minor version is an incompatible version?)
I had a rewrite on my hands either way, so I went looking for something else to rewrite in, and v3 is in Go. The other Python I was using in my VM build pipeline was replaced with a half-dozen lines of shell script. It’s much less flexible, perhaps, but it’s clear and concise now.
In the end, it seems that boring code survives the changing seasons. If you’re just making function calls and doing some regular expression work… there’s little that’s likely to change in that space. If you’re coloring functions and people are inventing brand-new libraries in the space you’re working in, your code will find its environment altered much sooner. The newer, fancier stuff is inherently closer to the fault-line of future shifts in the language semantics.