Update typing to CPython 3.8#2633
Conversation
|
Yeah, I think this involves implementing >>> list[int]
list[int]
>>> type(_)
<class 'types.GenericAlias'> |
I don't think that first one is in the "what's left" file.
Compare CPython 3.8: |
| class SupportsAbs(_Protocol[T_co]): | ||
| __slots__ = () | ||
|
|
||
| @abstractmethod | ||
| def __abs__(self) -> T_co: | ||
| pass |
There was a problem hiding this comment.
@coolreader18 this didn't fail in CPython 3.6 and it doesn't fail in RustPython. The only difference here (compared to line 1572 in the new file) in the class definition is the lack of an underscore before Protocol[T_co].
|
I grep'd the 3.8 branch of the CPython source code for certain things, and here's what I found: grep -Rn "__class_getitem__"grep -Rn "GenericAlias"grep -Rn "not subscriptable"Of the actual code files, I guess we can safely ignore EDIT: I found |
| #[pyclassmethod(magic)] | ||
| fn class_getitem(cls: PyTypeRef, _args: FuncArgs) -> PyObjectRef { | ||
| cls.into_object() | ||
| } |
There was a problem hiding this comment.
@coolreader18 Now that this is in the codebase, the next step is to tackle this problem TypeError: @runtime_checkable can be only applied to protocol classes, got <class 'typing.SupportsAbs'>. I don't think a class is inheriting correctly.
There was a problem hiding this comment.
If I remove the decorators I can see that the protocols are inheriting from typing._ProtocolMeta, which is the result of typing.Protocol[typing.T_co]. In CPython typing.Protocol[typing.T_co] returns an instance of typing._GenericAlias.
If I make my own class with __class_getitem__ the method is never called and type is always returned. If the class has a different metaclass that's returned instead.
I added some prints to the get_item method in pyobject.rs, and from that I can see vm.get_special_method(obj, "__class_getitem__") returns the method for type, rather than for the class itself. Again, if there's a metaclass its the method for the metaclass. Shouldn't this be calling the method on the class?
There was a problem hiding this comment.
Note on these changes. Why not add them in a separate PR? They will eventually be added, might as well add them before typing (since typing might need more time to land, right?).
There was a problem hiding this comment.
From my perspective, it makes more sense to reduce the number of PRs that have to be merged before this one, i.e. the dependencies of this PR. For really large changes it's good to split out into distinct features, but for relatively small ones it's fine to just have them as commits.
|
@oroppas you might want to follow the progress on this. |
|
@fanninpm do you have an auto formatter in your editor? It looks like formatting changed in the most recent commit |
@coolreader18 Thanks for catching that! I forgot to turn off |
|
That CI error seems to be because classes defined in Python are inheriting descriptors from |
20b9eb1 to
701b631
Compare
c.f. lines 2695-2725 of typeobject.c in CPython source
This restores an alteration made by @coolreader18 a while back.
They will be fixed later.
2d75f79 to
650b60c
Compare
|
@fanninpm @coolreader18 is there further works need to be done here? |
coolreader18
left a comment
There was a problem hiding this comment.
LGTM! Surprisingly small amount of changes to get this working :)
|
Although idk, maybe GenericAlias should be implemented as well? I don't think |
|
Meh, it'll hopefully be not too hard to implement. |
|
Thanks for working on this @fanninpm ! |
|
Ah, actually, 3.8 has no built-in GenericAlias. |
(Eventually, if this ends up getting merged, this will close #2622 and close #2658.)
I haven't gotten this module to import cleanly if I mostly take it from CPython 3.8 sources:
Line 1572 is the first occurence of a class inheriting from
Protocol[T_co]rather thanProtocol. Did the syntax change between CPython 3.6 and CPython 3.7?Let me know how we can get around this.