Hello,

I try to implement a patch for ``isinstance()`` and ``issubclass()``.
It's here <https://github.com/pprados/cpython/tree/updage_isinstance>
(variation possible). I not patch mypy now
<https://github.com/pprados/cpython/tree/updage_isinstance>

# Without patch and Tuple
$ ./python -m timeit -s 'isinstance("",(int,str))'
50000000 loops, best of 5: 6.29 nsec per loop

# With patch and Tuple
$ ./python -m timeit -s 'isinstance("",(int,str))'
50000000 loops, best of 5: 5.27 nsec per loop

# With patch and Union
$ ./python -m timeit -s 'isinstance("",int|str)'
50000000 loops, best of 5: 5.23 nsec per loop

Le sam. 7 sept. 2019 à 04:34, Andrew Barnert via Python-ideas <
python-ideas@python.org> a écrit :

> On Friday, September 6, 2019, 5:41:23 PM PDT, Steven D'Aprano <
> st...@pearwood.info> wrote:
>
> >On Fri, Sep 06, 2019 at 07:44:19PM +0000, Andrew Barnert wrote:
>
> >> > Union, and unions, are currently types:
> >>
> >> > py> isinstance(Union, type)
> >> > True
> >> >
> >> > py> isinstance(Union[int, str], type)
> >> > True
> >>
> >> What version of Python are you using here?
> >
> > Ah, I didn't realise that the behaviour has changed! I was using Python
> > 3.5, but I just tried again in 3.8:
>
> I didn't even consider that this might be an old feature that was taken
> away, rather than a new feature that was added. Oh well, at least it gave
> me an excuse to configure and build 3.9. :)
>
> > I don't know the reason for this change, but in the absense of a
> > compelling reason, I think it should be reversed.
>
> My thinking is in the opposite direction. I'm assuming Guido or Jukka or
> whoever wouldn't have made this change without a compelling reason. And if
> we can't guess that reason, then someone (who cares more about pushing this
> change than me) has to do the research or ask the right people to find out.
> Without knowing that, we can't really decide whether it's worth reversing
> for all types, or just for union types specifically, or whether the
> proposal needs to be rethought from scratch (or scrapped, if that's not
> possible), and the conservative default should be the last one.
>
> But hopefully the default won't matter, because someone will care enough
> to find out the reasons and report them to us. (Or maybe Guido will just
> see this discussion and have the answers on the top of his head.)
>
> > Steven (me):
>
> >> > But I disagree that int|str is a subclass of int|str|bytes. There's
> >> > no subclass relationship between the two: the (int|str).__bases__
> >> > won't include (int|str|bytes),
>
> > Andrew replied:
>
> > > First, `issubclass` is about subtyping, not about declared inheritance.
>
> > That could be debated. help(subclass) says:
>
> > "Return whether 'cls' is a derived from another class or is the same
> > class."
>
> > but of course ABCs and virtual subclassing do exist.
> > My position is that
> > in Python, issubclass is about inheritance, but you can fake it if you
> > like, in which case "consenting adults" applies.
>
> But it's not just a "consenting adults" feature that users can do whatever
> they want with, it's a feature that's used prevalently and fundamentally in
> the standard library—including being the very core of typing.py—and always
> with the consistent purpose of supporting (a couple of minor variations on
> the idea of) subtyping. So sure, technically it is inheritance testing with
> a bolt-on to add whatever you want (and of course historically, that _is_
> how it evolved), but in practice, it's subtype testing.
>
> Thanks to the usual practicality-beats-purity design, it isn't actually
> testing _exactly_ subtype either, of course. After all, while it would be
> silly to register `int` with `collections.abc.Sequence`, there's nothing
> actually stopping you from doing so, and that obviously won't actually make
> `int` a subtype of `Sequence`, but it will fool `issubclass` into believing
> it is. But, except when you're intentionally breaking things for good or
> bad reasons, what it tests is much closer to subtype than inheritance. In
> fact, even when you break things for good reasons, often it's to better
> match the subtyping expectation, not to violate it. (Consider `Sequence`
> and `Mapping`, which act as if they were structural subtyping tests like
> the other collection ABCs, despite the fact that it's actually impossible
> to distinguish the two types that way so they cheat with a registry. Try
> doing that with Swift or Go. :)
>
> > This Stackoverflow post:
> >
> > union types in scala with subtyping: A|B <: A|B|C
> <https://stackoverflow.com/questions/45255270/union-types-in-scala-with-subtyping-ab-abc>
> >
> > suggests that Scala considers that int|str is *not* a subtype of
> > int|str|bytes, but Scala.js considers that it is.
>
> Without reading the whole question carefully, and without refreshing my
> fuzzy memory of Scala's type system, I think there are two things going on
> here.
>
> First, the OP in that question seems to be trying to build his own
> disjunction type that acts like a union in other languages (including,
> apparently, Scala.js?), and he just didn't know how to code it right.
>
> So, why would anyone do that in the first place? Well, the bigger issue is
> that Scala's unions aren't quite the same thing we're talking about here in
> the first place—despite the fact that they're what inspired this whole
> thread. In most languages, the union of int and str is a special type
> that's defined by including all int values and all str values (and nothing
> else), or something similar to that. In Scala, the union of int and str is
> defined as the least upper bound of int and str on the lattice of all types
> (which of course provably does include all int values and all str values,
> because int and str are subtypes). In simple cases this ends up doing the
> same thing. And when they differ, it's usually that Scala can infer
> something cool that other languages can't. But I do vaguely remember one
> case where Scala couldn't infer a type for me and (unlike, say, Haskell or
> Kotlin—which may fail more often, but can always tell you exactly why they
> failed and what you need to add to fix it) it couldn't tell that it
> couldn't infer it, and it went and did something crazy like… an
> infinitely-long compile that ate up all my disk space or something? I
> forget.
>
> > But I will point out that the name of the function is *issubclass*, not
> > *issubtype*.
>
> Sure, and the `class` statement creates a `type` instance. Which are
> sometimes called `classes` and sometimes `types`. Since 2.3, all classes
> are types and all types are classes, and the root of the metaclass
> hierarchy is called `type`, and Python just mixes and matches the two words
> arbitrarily, and it almost never causes confusion. (Of course in pre-2.3
> Python, they were completely unrelated things, and `issubclass` only worked
> on classes, hence the name.)
>
> If you try and import a meaning from another language, then sometimes it
> can get confusing. But think about it: in, say, Java, "subclass" explicitly
> means only a concrete class inheriting implementation from another concrete
> class; a class implementing an interface is not subclassing. Which means a
> test for subclassing in the Java sense would be (a) not what Python does,
> and (b) pointless.
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/F7BFCNAIRTHH5QRHIBACN7B5U2LLRBU4/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/ZLKFABJ4SSJJNHFXOELY2QJEON7J7NLV/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to