> Yes, but then `isinstance(tuple(range(1000000)), Tuple[int, ...])` would be a difficult case.
Yes, many methods on million-element tuples are slow. :-) Python usually chooses the more intuitive behavior over the faster behavior when there is a choice. IIUC, the objections don't have anything to do with speed. - Lucas On Sun, Jun 25, 2017 at 10:11 AM, Koos Zevenhoven <k7ho...@gmail.com> wrote: > On Sun, Jun 25, 2017 at 7:13 PM, Lucas Wiman <lucas.wi...@gmail.com> > wrote: > [...] > >> >>> from typing import * >> >>> isinstance(0, Union[int, float]) >> Traceback (most recent call last): >> File "<stdin>", line 1, in <module> >> File "/Users/lucaswiman/.pyenv/versions/3.6/lib/python3.6/typing.py", >> line 767, in __instancecheck__ >> raise TypeError("Unions cannot be used with isinstance().") >> TypeError: Unions cannot be used with isinstance(). >> >> I think the natural reaction of naive users of the library is "That's >> annoying. Why? What is this library good for?", not "Ah, I've sagely >> learned a valuable lesson about the subtle-and-important-though-unmentioned >> distinction between types and classes!" The restriction against runtime >> type checking makes `typing` pretty much *only* useful when used with >> the external library `mypy` (or when writing a library with the same >> purpose as `mypy`), which is a pretty unusual situation for a standard >> library module. >> >> Mark Shannon's example also specifically does not apply to the types I'm >> thinking of for the reasons I mentioned: >> >>> For example, >>> List[int] and List[str] and mutually incompatible types, yet >>> isinstance([], List[int]) and isinstance([], List[str)) >>> both return true. >>> >>> There is no corresponding objection for `Union`; I can't think of any* >> inconsistencies or runtime type changes that would result from defining >> `_Union.__instancecheck__` as `any(isinstance(obj, t) for t in >> self.__args__`. >> > > One thing is that, as long as not all types support isinstance, then also > isinstance(obj, Union[x, y, z]) will fail for some x, y, z. From some > perspective, that may not be an issue, but on the other hand, it may invite > people to think that all types do support isinstance. > > For `Tuple`, it's true that `()` would be an instance of `Tuple[X, ...]` >> for all types X. However, the objection for the `List` case (IIUC; >> extrapolating slightly) is that the type of the object could change >> depending on what's added to it. That's not true for tuples since they're >> immutable, so it's not *inconsistent* to say that `()` is an instance of >> `Tuple[int, ...]` and `Tuple[str, ...]`, it's just applying a sensible >> definition to the base case of an empty tuple. >> >> > Yes, but then `isinstance(tuple(range(1000000)), Tuple[int, ...])` would > be a difficult case. > > I think it all comes down to how much isinstance should pretend to be able > to do with *types* (as opposed to only classes). Maybe isinstance is not > the future of runtime type checking ;). Or should isinstance have a third > return value like `Possibly`? > > -- Koos >
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/