Okay, here we go... I've got a bit to catch up on.
- I'm leaning towards closing my feature request, but I kind of want to see what other people think.
- I figured out how to write the plugin to catch problematic class definitions. It's a pretty gross implementation, though, so I'm looking into an alternative.
- If I'm writing a plugin anyway, the discussion on the feature request made me realize what I'd want a plugin to do.
Let's get right into it.
def saltate(typ: type[T], inst: Any, **changes: Any) -> T: return attrs.evolve(inst, **changes)
Plugin: ... like the new attrs plugin code, but unfortunately, more complicated. Basically, it needs to do all of the legwork of the builtin plugin, but also check that the underlying types of typ and inst "match", but need not unify, derive all arguments from typ, and mark any that are a different type from the attributes on inst as mandatory.
The basic concept here is that, because what I want is a kind of "discontinuous evolution", it's "saltation", and it needs to provide a specific target, as if it's a cast. This addresses some of the problems uncovered in the feature request discussion, and also hopefully makes it obvious that, hey, if you don't need to specify a type, probably just use evolve.
Unfortunately, it is too late at night for me to puzzle out plugin code right now, so I'm going to go over what else I did today.
- After getting a bunch of helper functions written earlier, I finally put it all together, and moved code out of the python module. At this point, it should be safe to create profiling wrappers.
- In order to have things work properly with the plugin I want to write, I finally unpinned Mypy from pre-1.0, addressed the type issues, one potentially valid and one that seems incredibly made-up to me, and then pinned to master, because otherwise I'd just have to pin to 1.1.*. I've got to say, I really hope I get Mypy yelling at me about unused type ignores from this, because I can't figure out which case I'm supposed to be hitting.
However, the more I think about it, the more I think "No, there has to be a way to make Mypy make sense here." So I guess I'm going to be bouncing off of that for a bit.
Okay, that's weird. I managed to get rid of one instance of the error by just annotating stuff until Mypy admitted there wasn't actually a problem, but it's not working a second time.
Okay, that's... not the greatest solution, but I can't find fault with it from a simple inspection perspective.
facts: _requirements.Requirements[_cmd.EnvVar[_cmd.CmdArg]] facts = value.map_facts(map_func) facts = typing.cast( "_requirements.Requirements[_cmd.EnvVar[_cmd.CmdArg]]", facts )
"What does the cast accomplish?"
It makes type-checking pass.
Anyway, now I've got a clean basis for working on saltate, but before that, I should probably try to extend the code some. It's possible I've forgotten some more improvements that I want to make. But for now, it's late.