
On Sep 4, 2019, at 01:29, Inada Naoki <songofacandy@gmail.com> wrote:
On Wed, Sep 4, 2019 at 1:15 PM Andrew Barnert via Python-ideas <python-ideas@python.org> wrote:
But that implies that you can also write this:
isinstance(x, Union[str, int])
… because, after all, str|int is defined as meaning exactly that. Which implies that the current rule that instantiated genetic types cannot be used for runtime type checks needs to be changed.
That’s certainly plausible, and maybe reasonable. But as I understand it, the idea that there things can’t be used for runtime type checks was a fundamental guiding principle to the typing design. So, it’s not something to be changed lightly. Someone has to go back to the reason for that principle (which may not be clearly stated anywhere, in which case it has to be extracted from things that _have_ been argued), and then make the case for why it should be violated here. And I haven’t seen anyone make that case. (If someone has and I missed it, apologies; chunks of this thread keep getting flagged as spam for some reason…)
I dislike runtime behavior of static types because I am very afraid accidental large performance or memory footprint regression.
ABC has extension module for speedup, but `isinstance([], Iterable)` is 4x slower than `isinstance([], (str, list)`.
Does the ABC use the extension module to speed up isinstance checks? (Couldn’t you just repeat your test with typing.Iterable—which can be tested; it’s only instantiated types like Iterable[int] that can’t, not the generics themselves—and see if it’s significantly slower than collections.abc.Iterable instead of guessing?) At any rate, both collections.abc and typing checks have to go through the metaclass and down into the class’s subclasscheck method and possibly do attribute checks and/or registry lookups, depending on the type (checking a list for Iterable I believe ends up passing the first test for __iter__, but only after getting that far into the process). Which is certainly slower than just iterating a tuple, which explains your 280 vs. 73. And that wouldn’t be any different for the types returned by Union.__getitem__. So, testing Union[int, str] is almost certainly going to be significantly slower than testing for (int, str), because it’ll be wrapping up the iteration over the types in a couple extra method lookups and calls. And you’re right, because int|str _looks_ better than (int, str) here, many people will be encouraged to use it even though it’s slower, which could potentially be a bad thing for some programs. Which means anyone proposing it now has to answer this performance issue, as well as researching and answering the other issue of whatever the reason is that for not allowing instantiated generics to typecheck in the first place.