<div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace"><span style="font-family:arial,sans-serif">On Thu, Jun 29, 2017 at 12:40 PM, Ivan Levkivskyi </span><span dir="ltr" style="font-family:arial,sans-serif"><<a href="mailto:levkivskyi@gmail.com" target="_blank">levkivskyi@gmail.com</a>></span><span style="font-family:arial,sans-serif"> wrote:</span><br></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div>Sorry, I was not able to completely digest the OP, but I think there are some points I need to clarify.<br><br></div>1. Distinction between runtime classes and static types is quite sane and a simple idea.<br>A runtime class is something associated with an actual object,<br>while static type is something associated with an AST node.<br></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></blockquote><div><br></div><div><div class="gmail_default" style="font-family:monospace,monospace">Here, ​I'm more concerned about *types* at runtime vs *types* for static checking. Some of these may be normal classes, but those are not the problematic ones.​</div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div></div>Mixing them would be misleading, since they "live in parallel planes".<br>Although it is true that there is a type that corresponds to every runtime class.<br></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></blockquote><div><br></div><div><br></div><div class="gmail_default"><font face="monospace, monospace">​It's not clear to me what you mean by mixing them. They are already partly mixed, right? <font color="#212121"><span style="font-size:13.3333px">I think you are speaking from the static-checker point of view, where there are only types, and runtime behavior is completely separate (at least in some sense). This view works especially well when types are in comments or stubs. But when the types are also present at runtime, I don't think this view is completely realistic. </span></font></font></div><div class="gmail_default"><font face="monospace, monospace"><font color="#212121"><span style="font-size:13.3333px"><br></span></font></font></div><div class="gmail_default"><font face="monospace, monospace"><font color="#212121"><span style="font-size:13.3333px">Some of the objects that represent types are regular classes, and some of them may be only types (like Union[str, bytes] or Sequence[int]), but not normal Python classes that you instantiate. Even if they represent types, not classes, they exist at runtime, and there should at least *exist* a well-defined answer to whether an object is in 'instance' of a given type. (Not sure if 'instance' should be world used here)</span></font></font></div><div class="gmail_default"><font face="monospace, monospace"><font color="#212121"><span style="font-size:13.3333px"><br></span></font></font></div><div class="gmail_default"><font face="monospace, monospace"><font color="#212121"><span style="font-size:13.3333px">Ignoring that *types* are also a runtime concept seems dangerous to me. </span></font></font></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div></div>2. Currently isinstance(obj, List[int]) fails with TypeError, ditto for issubclass and<br>for user defined generic classes:<br><br></div>class C(Generic[T]):<br>    ...<br><br></div>isinstance(obj, C)  # works, returns only True or False<br></div>isinstance(obj, C[int])  # TypeError<br></div>issubclass(cls, C)  # works<br></div>issubclass(cls, C[int])  # raisesTypeError<br><br></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></blockquote><div><br></div><div><div class="gmail_default" style="font-family:monospace,monospace">​I suppose that's the best that isinstance can do in these cases. But I'm not sure if isinstance and issubclass should try to do as much as reasonable, or if it they should just handle the normal classes, and let some new function, say implements(), take care of the other *types*. ​Anyway, this whole concept of two 'parallel universes' is problematic, because the universes overlap in at least two different ways.</div></div><div> </div><div><div class="gmail_default" style="font-family:monospace,monospace">​-- Koos​</div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div></div>3. User defined protocols will by default raise TypeError with isinstance(),<br>but the user can opt-in (using @runtime decorator) for the same behavior as normal generics,<br>this is how typing.Iterable currently works:<br><br></div>class MyIter:<br></div>    def __iter__(self):<br></div>        return [42]<br><br></div>isinstance(MyIter(), Iterable)  # True<br></div>isinstance(MyIter(), Iterable[int])  # TypeError<br><br></div>class A(Protocol[T]):<br></div>    x: T<br></div>isinstance(obj, A)  # TypeError<br></div><br></div>@runtime<br></div>class B(Protocol[T]):<br></div>    y: T<br></div>isinstance(obj, B)  # True or False depending on whether 'obj' has attribute 'y'<br></div>isinstance(obj, B[int])  # Still TypeError<br><br>--<br></div>Ivan<br><br><br></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">+ Koos Zevenhoven + <a href="http://twitter.com/k7hoven" target="_blank">http://twitter.com/k7hoven</a> +</div>
</div></div>