Hatch v1.8.0 brings Python distribution management, static analysis and formatting backed by Ruff, and binaries for every platform.
Installation made easy¶
One thing that has been a perpetual problem for Hatch and other Python applications is that Python itself is a dependency. You, and more importantly your users, need to in some way get Python before your software can even be used. The recommended way to go about that is platform-dependent and even differs based on your target audience. I viewed this as a central UX problem for Hatch and so severe that I took a bit of a hiatus to solve it.
Luckily, I have to my satisfaction solved this problem in the form of PyApp. It is a runtime installer for Python projects written in Rust. Apps are distributed as standalone executables as users have come to expect and bootstrapping occurs upon the first invocation. Here is an example of what you would see the first time you run a binary from this release:
Now that we have binaries, creating installers for different platforms becomes trivial. Starting with this release not only are binaries available for every platform but also we have installers for Windows and macOS. The installer for macOS is signed using a certificate from the same account used to sign the official distributions from https://www.python.org, so users will not get any security pop-ups. Shout out to @ewdurbin for their extreme generosity in setting up multiple certificates in their free time!
These installers and binaries are now the recommended way to install and update Hatch. These binaries have built-in management so you can update to the latest version by running
hatch self update.
In future we will sign the installers for Windows but I did not have time to look into how that works. macOS signing took way longer than I anticipated
For a long time I and other users have desired that Hatch gain the ability to manage Python distributions. In my mind this was always blocked on a better installation experience because there was sort of a chicken-or-egg problem where you want a Python manager but you first need Python. No longer is that the case!
python command group allows for easy installation of various distributions to arbitrary locations which are then added to your PATH by default. Hatch supports CPython and PyPy distributions:
Virtual environment Python resolution¶
virtual environment type is now far more intelligent when resolving the parent distribution to use and guarantees that, when no specific version is requested, the resolved distribution will always be compatible with the project.
Additionally, when a requested version cannot be found on PATH it will automatically be downloaded and managed internally.
Starting with this release, Hatch maintains default settings that are guaranteed to be up-to-date and represent best practices for programming in modern Python. The idea is to provide defaults that are so broadly applicable that the majority of users will maintain little if any of their own overrides.
The default behavior is internal management of settings to provide an OOTB experience that works. It is recommended however that you persist the default config file in version control so that other tools like IDEs can utilize your full configuration.
Since Ruff is now provided as a built-in feature, new project templates no longer have such configuration and are much less verbose.
The bridge between Hatch and the Hatchling CLI has been removed. Previously, the builder would send serialized messages to Hatch that would contain the desired content and style for each line of output. This was done in an effort to allow builder and build hook plugins to output pretty messages without actually requiring a dependency like Rich. A problem that arises with this is that builders that invoke subprocesses will not display ANSI codes as one might expect and will lose out on the interactive experience of such invocations, like the built-in app builder plugin calling
cargo build. So now everything is simpler at the expense of no colored output without manual logic, or adding a dependency if you're a third-party plugin.
Faster environment usage¶
Spawning a shell or running commands within environments always first checks that your project's dependencies are satisfied and if not synchronizes the environment with what is defined. Previously, this had the potential to be quite slow for projects that have many dependencies.
Now the set of dependency definitions is hashed and no check is performed if the hash is the same as before, significantly speeding up environment usage in most cases.
Hatch now depends on Hatchling v1.19.0, which was also just released.
Hatchling is all about providing the best possible defaults, even at the expense of backward compatibility. In this release, there are two breaking changes that provide a much better user experience and were in fact requested by users.
- Both the
force-includeoption and the
force_include_editablewheel build data setting now raise errors if source paths do not exist.
wheelbuild target now raises an error when no file inclusion options have been defined and none of its heuristics to determine what to ship are satisfied.
App build target¶
app build target is now stable that allows for the building of standalone binaries for projects. This is what Hatch itself uses for its binaries.
A new page has been introduced that discusses the value proposition of Hatch and Hatchling in comparison to alternatives. Currently, it only addresses a few features but in future this page will become more comprehensive.
Upcoming features include a
test command, commands to manage dependencies, and workspaces functionality similar to Cargo that will make managing monorepos far easier.
Next year there will be two large efforts that you should expect to see:
A significant amount of my free time (and some at work) will be devoted to introducing lock file functionality in Hatch and trying to get whatever that happens to be standardized.
I met with @brettcannon about his thoughts post-PEP 665 and about mousebender. I also met with the prefix.dev team about rip and was fortunate enough to be shown a demo before its official announcement.
At the moment, the two options I see are to either go all in and contribute to mousebender or rely on the Prefix folks and use rip. The latter has the benefit of potentially supporting Conda as a side effect with the downside of being quite new with the spec firmly out of our control. The former has the benefit of being able to easily gain institutional support from the Python packaging team and each of our employers with the downside being a significant amount of work needing to be done.
I am of the opinion that the Python community has not fully completed the expressed outcome of PEP 517 in that build backends are still (for the most part) reliant on setuptools for building non-Python code bases.
Basically, there are components that interact with compilers to produce extension modules and components that pack files into an archive which we call a build backend. These are two distinct pieces of functionality and my view is that there should be an API that allows backends to consume extension module builders to find out where things got created and where they should be shipped inside archives.
In this hypothetical future any build backend would be able to trigger the building of extension modules based on user configuration.
If you or your organization finds value in what Hatch provides, consider a sponsorship to assist with maintenance and more rapid development!