[Python-Dev] Python3.7 backwards incompatible

Ivan Levkivskyi levkivskyi at gmail.com
Sat Jun 23 21:14:55 EDT 2018


This particular breakage is explicitly listed in PEP 560, see an example
with List and List[int] in
https://www.python.org/dev/peps/pep-0560/#backwards-compatibility-and-impact-on-users-who-don-t-use-typing

In general, isinstance() with typing types should be avoided when possible
(Mark Shannon who is the BDFL delegate for PEP 484 wanted to prohibit it
completely, but in the end we kept only the bare minimum, like your first
example).

When designing/implementing PEP 560 I realised it will be impossible to
keep 100% backwards compatibility. I tried to preserve 99% of public APIs,
but since isinstance() is already discouraged, it fell into remaining 1%.

A possible workaround is to use `typing_inspect` library on PyPI
(disclaimer: I originally wrote it). You can use `get_origin()` function to
extract the runtime class that corresponds to a given type. It works with
both 3.6 and 3.7 and tries its best to return the relevant runtime class
(with few exceptions, see docstring), for every version, for example on
Python 3.7 `get_origin(List[int])` return `list`. The return of
get_origin() should be usable in all runtime context including
`isinstance()`.

Btw, I actually like the new behaviour. After PEP 560 types are no more
classes, which emphasises that they should be used in static context, if
one wants to do something in runtime, one needs to use an explicit
conversion to a runtime class.

--
Ivan



On 23 June 2018 at 23:10, Guido van Rossum <guido at python.org> wrote:

> First, the typing module is still provisional, so there is no strict
> backwards compatibility guarantee.
>
> With that out of the way, I can reproduce your problem, and I assume it's
> caused by the implementation of PEP 560, which is meant to speed up the
> typing module (among other goals).
>
> I'm wondering about your claim that this breaks many "libraries that use
> annotations". Most code using annotations would not need to use
> issubclass() in this way. Where exactly did you encounter this?
>
> I'm CC'ing Ivan Levkivskyi, who knows the relevant code better and will be
> able to explain whether this is an oversight or an intentional regression.
>
> On Sat, Jun 23, 2018 at 2:59 PM Rokker Ruslan <rokkerruslan at yandex.com>
> wrote:
>
>> Python 3.7 in the status of RC, but I do not see information about the
>> fact that python3.7 is backwards incompatible with python3.5.
>>
>> $ ~ python3.5
>> Python 3.5.2 (default, Nov 23 2017, 16:37:01)
>> [GCC 5.4.0 20160609] on linux
>> Type "help", "copyright", "credits" or "license" for more information.
>> >>> from typing import List
>> >>> class MyList(list):
>> ...     pass
>> ...
>> >>> issubclass(MyList, List)
>> True
>> >>> issubclass(List, MyList)
>> False
>> >>>
>>
>> $ ~ python3.7
>> Python 3.7.0rc1+ (heads/3.7:3747dd16d5, Jun 22 2018, 22:53:42)
>> [GCC 5.4.0 20160609] on linux
>> Type "help", "copyright", "credits" or "license" for more information.
>> >>> from typing import List
>> >>> class MyList(list):
>> ...     pass
>> ...
>> >>> issubclass(MyList, List)
>> True
>> >>> issubclass(List, MyList)
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>> TypeError: issubclass() arg 1 must be a class
>> >>>
>>
>> And so with all types of "typing" module.
>> This breaks down many libraries that use annotations as part of the
>> functionality if we now can't use typing.* into issubclass function.
>> _______________________________________________
>> Python-Dev mailing list
>> Python-Dev at python.org
>> https://mail.python.org/mailman/listinfo/python-dev
>> Unsubscribe: https://mail.python.org/mailman/options/python-dev/
>> guido%40python.org
>>
>
>
> --
> --Guido van Rossum (python.org/~guido)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180624/3e4bf6dc/attachment.html>


More information about the Python-Dev mailing list