<@UB2J9BQA0>: random, but while looking at <https:...
# development
w
@hundreds-father-404: random, but while looking at https://github.com/pantsbuild/pants/issues/9760 , i realized that in many cases the “memoized anonymous class” strategy can typecheck fine… the only time it won’t is when the subclass needs to be treated as the subclass (that would require casting). otherwise you can type it like:
Copy code
class SS:
    @memoized
    @classmethod
    def scoped_to(cls, name: str) -> Type["SS"]:
        class AnonymousSub(SS):
            pass
        return AnonymousSub
ie, if you are ok with losing the precise type in mypy, you’re good. it’s still a distinct, unique subclass at runtime… which is sufficient for unions/the-engine
so, that means it would work for
Target.Fields
, and for the usecase on #9760.
but it did not work for
Options
(afaik) because we wanted to preserve the subtype to be able to call methods on it and/or see which options were valid
(although as i say that, i’m not sure it’s true, because Options instances don’t have any unique fields, so you never need the more precise type)
h
Target.Fields
? Like union fields?
w
yea, i forget where it is
h
Oh, I think you mean
.PluginField
, which John found is the same for every target type
w
right. so: it doesn’t need to be if you use the anonymous class with memoization.
it can in fact be a distinct type: see the example above
👀 1
h
I’m confused why
AnonymousSub
subclasses the superclass. Is that necessary?
w
yes: to typecheck
it is a subclass of the type you’re returning
you’re not declaring its precise type: you’re just saying that you’re returning a subtype of
SS
👍 1
cc @enough-analyst-54434: ^ fyi
e
K. I still think modeling fields you add to a target as subclasses of some marker field type + warping Union is all tortured vs directly lifting this as 1st class concept - just register the plugin field directly, but Its already modeled that way though, so this does no extra harm and rights the ship at least.
👍 1