Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E721: suggest reasonable alternative #882

Open
Kaligule opened this issue Aug 23, 2019 · 12 comments
Open

E721: suggest reasonable alternative #882

Kaligule opened this issue Aug 23, 2019 · 12 comments

Comments

@Kaligule
Copy link

Kaligule commented Aug 23, 2019

E721 is there to prevent type(3) == int in favour of isinstance(3, int). Thats fine.

But it also raises an error for code like type(a) == type(b). This is good code though and I don't know of a better way to test if two values have the same type. Of course you can go for isinstance(a, type(b)), but that is longer and less readable.

I suggest either changing E721 to not match lines like the above or to suggest a reasonable alternative to the line above.

@sigmavirus24
Copy link
Member

Is isinstance(b, type(a)) a reasonable alternative?

@Kaligule
Copy link
Author

I don't think so (as mentioned above) because it is

  1. less readable
  2. longer

I am also not sure what would happen if b was a subtype of a.

There is also not really a reason to use this more complicated way - it doesn't have any advantage to the simpler version.

@asottile
Copy link
Member

I believe type(a) is type(b) would be an improvement for the second case you've suggested?

@Kaligule
Copy link
Author

Kaligule commented Apr 30, 2020

I would like that. I am not 100% sure if it would work by default (I would have to dig into the differences between == and is to find out).

@asottile
Copy link
Member

the only way it could differ is if the metaclass for the particular type overrides __eq__ in a strange way (this is exceedingly unlikely)

@hoylemd
Copy link

hoylemd commented Apr 30, 2020

I'm always in favour of more usages of is operator.

@sigmavirus24
Copy link
Member

@Kaligule Ned Batchelder has a good succinct talk (& accompanying blog post iirc) on this from a while ago that I'm sure is easily searchable

@sigmavirus24
Copy link
Member

@hoylemd
Copy link

hoylemd commented May 1, 2020

TL;DR of the blog post:

is is not the same as ==. It tests identity, not equality, and that can be misleading.

If types (as returned by type()) are singletons like None, then it should work. I would expect most primitive types (str, int etc) would effectively be singletons, not so sure for classes though.

@sigmavirus24
Copy link
Member

The gotcha would be if you have a case where some popular library vendors its dependencies and you're also on an Operating System that distributes its own versions of this library with the dependencies unvendored. In that case you might import depA and pass that into import popularLibrary which would then say if popularLibrary.vendored.depA.Class is userProvidedDepA.Class then you'd have issues due to import path. Assuming that's not a situation that most people encounter (and don't ask how I've encountered it) then is should be mostly safe.

@hoylemd
Copy link

hoylemd commented May 4, 2020

@sigmavirus24 Well now I want to ask how you encountered that haha.

It's important to identify those rare corner cases though. I think the more pertinent question is whether is is/should be safe enough for pycodestyle to suggest it's use in these cases. Do you think situations like the one you described are common enough not to suggest using is without qualification?

@sigmavirus24
Copy link
Member

Do you think situations like the one you described are common enough not to suggest using is without qualification?

No.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants