[Python-Dev] Comments on PEP 560 (Core support for typing module and generic types) (original) (raw)
Mark Shannon mark at hotpy.org
Mon Nov 20 04:22:16 EST 2017
- Previous message (by thread): [Python-Dev] Comments on PEP 560 (Core support for typing module and generic types)
- Next message (by thread): [Python-Dev] Comments on PEP 560 (Core support for typing module and generic types)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 19/11/17 22:36, Ivan Levkivskyi wrote:
On 19 November 2017 at 21:06, Mark Shannon <mark at hotpy.org_ _<mailto:mark at 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 changingobject._getitem_
, but that is still a major change to the language.Except that there is no such thing as object.getitem. Probably you_ mean PyObjectGetItem (which is just what is done by BINARYSUBSCR 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, classgetitem is searched on the object (class object in this case) itself. But this is clearly explained in the PEP. In fact, the addition of
_mroentries_
makes_classgetitem_
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
_mroentries_
suggests that this method is solely related method resolution order, but it is really about providing an instance oftype
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_mroentries_
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
andissubclass
call_mroentries_
before raising an error if the second argument is not a class? In other words, ifList
implements_mroentries_
to returnlist
then shouldissubclass(x, List)
act likeissubclass(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.
- Previous message (by thread): [Python-Dev] Comments on PEP 560 (Core support for typing module and generic types)
- Next message (by thread): [Python-Dev] Comments on PEP 560 (Core support for typing module and generic types)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]