
On Fri, Dec 24, 2021 at 9:38 AM Anton Agestam <antonagestam@gmail.com> wrote:
(Hoping I figured out how to reply in the thread now... )
(Almost. Your message came through (we have moderation for new list members because of insistent spammers) but my mail reader doesn't show it in the same thread. That happens a lot so let's not worry about it.)
Yes, sorry for the cryptic message but it looks like you got it right. The example isn't impressive but just like Steven is saying the value comes in larger applications. In a web application for instance only the parsing layer will have to deal with the runtime validation of the type. The business logic and database layers can use static type checking to make sure only the narrowed value is allowed. So it's kind of like a NewType plus an "instantiation predicate" (I'm failing to find the correct term, nothing is actually instantiated).
Let me see if I understand what happens here ( https://github.com/antonagestam/phantom-types/blob/main/README.md#examples), without trying to understand the source code: class Name(str, Phantom, predicate=contained({"Jane", "Joe"})): ... greet(Name.parse("Jane")) To the static type checker (mypy, Pyre, pyright etc.) the argument to greet() has type Name, which is a class. But at runtime its __class__ is just str -- but through the magic of __instancecheck__, isinstance("Joe", Name) still returns True. This is indeed cool. It's also cool that because of the isinstance() trick, static checkers will narrow the type correctly after 'if isinstance(x, Name)' or 'assert isinstance(x, Name)'. I suppose there's some caching going on as well? (Throwing in an lru_cache somewhere would seem easy and I can't see a downside.) I'm curious if this is still useful if you want to parse a longer string into components. Could this be made to parse a long string into an HTTP header struct returning a dic[str, str] (or whatever data structure is appropriate)?
I thought it's relevant here since I imagine a NotType would also have to rely a lot on runtime narrowing. If a downstream API takes Sequence & Not[str] and we have a Sequence available, we'd have to narrow it with something like assert not isinstance(..., str).
That makes sense, although the more likely scenario is that the value we have in hand is known to be a list[str], for example. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>