On 19/11/17 22:36, Ivan Levkivskyi wrote:
On 19 November 2017 at 21:06, Mark Shannon <m...@hotpy.org
<mailto:m...@hotpy.org>> wrote:
By far and away the largest change in PEP 560 is the change to the
behaviour of object.__getitem__. This is not mentioned in the PEP at
all, but is explicit in the draft implementation.
The implementation could implement `type.__getitem__` instead of
changing `object.__getitem__`, but that is still a major change to
the language.
Except that there is no such thing as object._getitem__. Probably you
mean PyObject_GetItem (which is just what is done by BINARY_SUBSCR opcode).
Yes, I should have taken more time to look at the code. I thought you
were implementing `object.__getitem__`.
In general, Python implements its operators as a simple redirection to a
special method, with the exception of binary operators which are
necessarily more complex.
f(...) -> type(f).__call__(f, ...)
o.a -> type(o).__getattribute__(o, "a")
o[i] -> type(o).__getitem__(o, i)
Which is why I don't like the additional complexity you are adding to
the dispatching. If we really must have `__class_getitem__` (and I don't
think that we do) then implementing `type.__getitem__` is a much less
intrusive way to do it.
In fact, I initially implemented type.__getitem__, but I didn't like it
for various reasons.
Could you elaborate?
I don't think that any of the above are changes to the language. These
are rather implementation details. The only unusual thing is that while
dunders are
searched on class, __class_getitem__ is searched on the object (class
object in this case) itself. But this is clearly explained in the PEP.
In fact, the addition of `__mro_entries__` makes `__class_getitem__`
unnecessary.
But how would you implement this:
class C(Generic[T]):
...
C[int] # This should work
The issue of type-hinting container classes is a tricky one. The
definition is defining both the implementation class and the interface
type. We want the implementation and interface to be distinct. However,
we want to avoid needless repetition.
In the example you gave, `C` is a class definition that is intended to
be used as a generic container. In my mind the cleanest way to do this
is with a class decorator. Something like:
@Generic[T]
class C: ...
or
@implements(Generic[T])
class C: ...
C would then be a type not a class, as the decorator is free to return a
non-class object.
It allows the implementation and interface to be distinct:
@implements(Sequence[T])
class MySeq(list): ...
@implements(Set[Node])
class SmallNodeSet(list): ...
# For small sets a list is more efficient than a set.
but avoid repetition for the more common case:
class IntStack(List[int]): ...
Given the power and flexibility of the built-in data structures,
defining custom containers is relatively rare. I'm not saying that it
should not be considered, but a few minor hurdles are acceptable to keep
the rest of the language (including more common uses of type-hints) clean.
The name `__mro_entries__` suggests that this method is solely
related method resolution order, but it is really about providing an
instance of `type` where one is expected. This is analogous to
`__int__`, `__float__` and `__index__` which provide an int, float
and int respectively.
This rather suggests (to me at least) the name `__type__` instead of
`__mro_entries__`
This was already discussed during months, and in particular the name
__type__ was not liked by ... you
Ha, you have a better memory than I :) I won't make any more naming
suggestions.
What I should have said is that the name should reflect what it does,
not the initial reason for including it.
https://github.com/python/typing/issues/432#issuecomment-304070379
So I would propose to stop bikesheding this (also Guido seems to like
the currently proposed name).
Should `isinstance` and `issubclass` call `__mro_entries__` before
raising an error if the second argument is not a class?
In other words, if `List` implements `__mro_entries__` to return
`list` then should `issubclass(x, List)` act like `issubclass(x, list)`?
(IMO, it shouldn't) The reasoning behind this decision should be
made explicit in the PEP.
I think this is orthogonal to the PEP. There are many situations where a
class is expected,
and IMO it is clear that all that are not mentioned in the PEP stay
unchanged.
Indeed, but you do mention issubclass in the PEP. I think a few extra
words of explanation would be helpful.
Cheers,
Mark.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com