[issue44293] PEP 585 breaks inspect.isclass

2021-06-05 Thread Ivan Levkivskyi


Ivan Levkivskyi  added the comment:

Uploaded typing_inspect 0.7.0 to PyPI (it should work with Python 3.9 hopefully)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44293] PEP 585 breaks inspect.isclass

2021-06-03 Thread Ivan Levkivskyi


Ivan Levkivskyi  added the comment:

Btw this reminds me I should make a PyPI release of typing_inspect (last 
release was May 2020), hopefully will make a release on this weekend.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44293] PEP 585 breaks inspect.isclass

2021-06-03 Thread Guido van Rossum


Guido van Rossum  added the comment:

Instead of introspecting types, use this library:
https://github.com/ilevkivskyi/typing_inspect

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44293] PEP 585 breaks inspect.isclass

2021-06-03 Thread Ken Jin


Ken Jin  added the comment:

@Jelle thanks for nosy-ing me too and the thorough investigation.

@Joseph

Thanks for taking the time to raise this inconvenience on the bug tracker.

> By the way, Python typing is so much unstable (every version breaks the 
> previous one), it's very complicated to write code that support multiple 
> versions, so whatever the typing internal implementation, we must adapt.

Compared to some of the more mature modules in Python, I have to agree that 
typing.py is mildly unstable. However, you're not supposed to be 
using/importing from the internal constructs - those have no guarantee of 
stability. If you feel some common use cases aren't met by the current 
introspection helpers, please please please create a new issue for that and 
we'll consider it. How we use typing may differ from how you use it and so 
there's a lot we don't see. User bug reports and feedback have helped to 
surface such issues and improved typing for everyone :). 

> I have chosen `list[int]` as an example of `types.GenericAlias` introduced by 
> PEP 585 (i could have chosen `set[int]` or 
> `collections.abc.Collection[int]`). But other generic aliases, e.g. 
> `typing.List[int]` or `MyClass[int]` (where `MyClass` inherits `Generic[T]`), 
> are not instances of `type`.

This is an implementation detail. Most typing PEPs don't usually specify the 
runtime behavior in detail because most of them focus on static analysis. The 
implementation is usually up to the contributor's judgement. FWIW, to 
accommodate the new 3.9 GenericAlias, typing.py just added additional checks 
for `isinstance(tp, types.GenericAlias)` instead of checking only for 
`isinstance(tp, type)` and friends.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44293] PEP 585 breaks inspect.isclass

2021-06-03 Thread Joseph Perez


Joseph Perez  added the comment:

@Jelle Zijlstra Thank you for the explanation.

> The current implementation of GenericAlias has been around for a few releases 
> by now, though, so that change might break some use cases.

I agree that a "fix" could have unexpected side-effect, my issue comes quite 
late indeed. By the way, Python typing is so much unstable (every version 
breaks the previous one), it's very complicated to write code that support 
multiple versions, so whatever the typing internal implementation, we must 
adapt.

> This is not true; it is the same for e.g. `set[int]`. Unless you meant 
> something else here.

I have chosen `list[int]` as an example of `types.GenericAlias` introduced by 
PEP 585 (i could have chosen `set[int]` or `collections.abc.Collection[int]`). 
But other generic aliases, e.g. `typing.List[int]` or `MyClass[int]` (where 
`MyClass` inherits `Generic[T]`), are not instances of `type`.

> @Joseph Perez, is there a specific library or pattern that is broken by this?

Because `issubclass` requires a "class" as arg 1, I use the pattern `if 
isinstance(tp, type) and issubclass(tp, SomeClass)` (`isinstance` check being 
equivalent to `inspect.isclass`). With PEP 585, it breaks for `list[int]` and 
other builtin generic aliases.

> FWIW I did think rather carefully about which attributes to delegate or not, 
> and delegating __class__ was intentional.

I don't have the context of the decision, so I can quite understand that 
delegating `__class__` was the right thing to do, especially when `__mro__` and 
other `type` attributes are also delegated. 
I mainly wanted to highlight this side effect, especially on the pattern 
mentioned above. (My issue title is a little bit excessive in this regard)

But as I've written, I've already so many wrappers to maintain compatibility 
between Python versions of typing that I can write a new one to handle this 
particularity of PEP 585. So this issue is not critical to me.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44293] PEP 585 breaks inspect.isclass

2021-06-02 Thread Guido van Rossum


Guido van Rossum  added the comment:

Since these are new forms (list[int] previously was an error), does it actually 
matter? Especially since these are primarily used in annotations.

@Joseph Perez, is there a specific library or pattern that is broken by this?

FWIW I did think rather carefully about which attributes to delegate or not, 
and delegating __class__ was intentional.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44293] PEP 585 breaks inspect.isclass

2021-06-02 Thread Jelle Zijlstra


Jelle Zijlstra  added the comment:

The reason for this is that types.GenericAlias.__getattribute__ delegates to 
the alias's origin (in the `ga_getattro` function). As a result, 
`list[int].__class__` calls `list.__class__` and returns `type`. And the 
implementation of `isinstance(obj, type)` ultimately calls 
`issubclass(obj.__class__, type)`. (That's in `object_isinstance()` in 
abstract.c. It's news to me; I didn't know you could customize isinstance() 
behavior on the object side.)

To fix this, we could make `ga_getattro` not delegate for `__class__`, so that 
`list[int].__class__` would return `GenericAlias` instead of `type`. The 
current implementation of GenericAlias has been around for a few releases by 
now, though, so that change might break some use cases.

> This is not the case for other generic aliases.

This is not true; it is the same for e.g. `set[int]`. Unless you meant 
something else here.

--
nosy: +Jelle Zijlstra, gvanrossum, kj, levkivskyi

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue44293] PEP 585 breaks inspect.isclass

2021-06-02 Thread Joseph Perez


New submission from Joseph Perez :

PEP 585 has the side-effect of making `list[int]` an instance of `type`. This 
is not the case for other generic aliases.

It also implies that `inspect.isclass(list[int]) is True`, while `list[int]` is 
not a class; as a proof of this statement `issubclass(list[int], 
collections.abc.Collection)` raises `TypeError: issubclass() arg 1 must be a 
class`.

By the way, there is the awkward thing of having `isinstance(list[int], type) 
is True` while `issubclass(type(list[int]), type) is False`.

--
messages: 394950
nosy: joperez
priority: normal
severity: normal
status: open
title: PEP 585 breaks inspect.isclass
versions: Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com