Coding 2020-11-09
I forget exactly what I did today. I think it was some coverage improvements and fixes, as well as the minor changes I was talking about yesterday.
Still pondering the way to handle the roll stuff for Mythic. What I'm leaning towards is, a given roll needs to be in the context of a particular player/sheet. It also needs associated global information. So, if there's a way to inject a SheetProxy...
Ugh, dammit. If I try to do this in the way that I think of as simple and obvious, I'm going to run into a limitation in punq that confused me so hard when I first ran into it.
Here's the deal:
punq is a library for performing dependency injection, and it can be used to make functions have flexible behavior without cluttering their interfaces. Basically, by inspecting the annotations associated with a callable object, it figures out which other callables it needs to use to get the required arguments. It also has the ability to specify associated values at resolution time, but such values are passed as keyword arguments, so they effectively must be string keys. There are facilities for translating between string and type in some direction or other, but I do not trust them. I try to avoid them, but to some extent, it's not possible. This is because using string and type annotations that are equivalent from a typing analysis perspective leads to different behavior when punq analyzes them.
import attr
import punq
class Target:
pass
@attr.dataclass
class WithType:
field: Target
@attr.dataclass
class WithStr:
field: "Target"
punq.Container().register(WithType) # Works
punq.Container().register(WithStr) # Raises exception from within punq
It seems to me like "define a string type annotation that gets filled in at runtime" would be a really useful pattern, but I'm not sure how to, like, do it.
Unless... I've got an attempt at a fork that rectifies some of my complaints with punq. I can just take that, and any changes to punq since, and make a local copy within the repo. Thanks to my workarounds to the pip issues I was hitting earlier, that should just work, and give me some real-world proving-out of this stuff.
... I opened the PR against punq earlier this year‽ That's it, time is definitely fake. Fortunately, this means there's only a minor update required. I'll get to work on this tomorrow.
I think the correct order to do things is:
- Copy code from the main punq repo. Get everything set up as I want, but leave the code itself be.
- Make sure it properly shadows everything, and still works.
- Archive the repo at that point, because I'm not super conversant with non-trivial pijul usage.
- Run black over the codebase.
- Address any coverage holes. (punq's coverage badge is broken, so I don't know what to expect; also it's almost certainly not compatible with limit-coverage, which will be... a barrier to merging back.)
- Look over the changes from my PR, and either redo them, or do something different.
- See how well or poorly my fork works when used in anger.
- Consider propagating the changes back to my own upstream, and committing to either a merge or a fork.
Those are big plans, and it's late.
Good night.