Coding 2021-12-01
I ended up getting a bit distracted improving the typing strictness in MOTR, part of which ended up turning into PRs against other libraries. I... did not do so great with those PRs; I assume they'll get moving in a bit. (This would all be so much easier if pylint would stop regressing things when it updates...)
Anyway, I have some stub classes for implementing the Pip versions of the Protocols I need, so let's zoom in on what needs to happen there.
- For now, I want the Installer to just build up a command line and not deal with environment variables or extra IO data.
- The command line must support Input values.
- The root for now is pip install, and I think I can get by with just -c <file>, -r <file>, and string literals for things to concatenate onto it.
- The string literals should be validated to not start with -, at minimum. (I think.)
- The other side of the installer is the combination of "data that determines the root" and "key for retrieving Python version".
- The Installation class needs the ability to associate Output values with the pip install command. I can either do this the direct hacky way, or the duplication of effort way. An alternative possibility would be to turn Installation into a concrete type that simply combines an Installer and some registries, then delegates the underlying functionality to a method on the Installer. Honestly, I think that makes more sense, so let's see what needs to happen for that...
All right, that was pretty painless. So, let's see what this new Pip class, that I got from not needing to note the kind of class, will need.
- Sequence of path segments, and property to convert them into a relative path
- Setlike collection of command components, and property to convert them into a command
- Python version key
It needs to convert all of that into a working environment, and it does so as follows:
- Resolve the version key against the registries
- Determine the path of the environment root
- Create the parent directory
- Create the environment with the specified python version
- Resolve the command within the environment, convert to Input
- Convert the Input to an Output in the context of the pip command, and run it.
- Return the Input
I thought I might need something a bit more involved in some cases, but I suspect I was misreading the Mypy documentation. It would be best to do the following things:
- Create a specific data type for (Key[Installer], str) pairs, so I'm not keying off whether something is a tuple.
- Prioritize support for PyPy2 once I've got the basics of everything working.
I'm also going to need to review how I'm going to fit using pyproject-build into this flow, because that's going to be the code responsible for generating a bunch of the requirements and constraints files, and it's also complex enough that it can't fit into the same ecosystem that it's going to be supporting.
So, things to work on now:
- Create the new compound type for getting command paths
- Write the helper methods to process it and patch those into the existing code
- Write the helper types to support pip command generation
- Add all required fields to the Pip object
- Write the combine method
- Write the resolve method ASAP
- Port over the code from the motrfile that invokes pyproject-build
Actually, it's occurring to me that I should really be able to construct a pip command without needing to rely on the Key stuff directly, by leveraging Builders.
I made the changes now, and I'll see what I think of all that later. It might be somewhat unfortunate that I can't be completely consistent about removing late binding, because that's what the Command object must do, but oh well, this should simplify some things, I think/hope. Or maybe the interface comes out looking virtually identical, but the Installer Protocol is theoretically more flexible.
It's all good. Anyway, I'm going to wrap up for now, and start working on that list later.
Good night.