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

isinstance() should respect __class__ #36297

Closed
steveazope mannequin opened this issue Mar 20, 2002 · 8 comments
Closed

isinstance() should respect __class__ #36297

steveazope mannequin opened this issue Mar 20, 2002 · 8 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs)

Comments

@steveazope
Copy link
Mannequin

steveazope mannequin commented Mar 20, 2002

BPO 532767
Nosy @gvanrossum, @loewis

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/gvanrossum'
closed_at = <Date 2003-02-12.03:41:06.000>
created_at = <Date 2002-03-20.22:22:56.000>
labels = ['interpreter-core']
title = 'isinstance() should respect __class__'
updated_at = <Date 2003-02-12.03:41:06.000>
user = 'https://bugs.python.org/steveazope'

bugs.python.org fields:

activity = <Date 2003-02-12.03:41:06.000>
actor = 'gvanrossum'
assignee = 'gvanrossum'
closed = True
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2002-03-20.22:22:56.000>
creator = 'stevea_zope'
dependencies = []
files = []
hgrepos = []
issue_num = 532767
keywords = []
message_count = 8.0
messages = ['9841', '9842', '9843', '9844', '9845', '9846', '9847', '9848']
nosy_count = 3.0
nosy_names = ['gvanrossum', 'loewis', 'stevea_zope']
pr_nums = []
priority = 'high'
resolution = 'accepted'
stage = None
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue532767'
versions = ['Python 2.3']

@steveazope
Copy link
Mannequin Author

steveazope mannequin commented Mar 20, 2002

isinstance(obj, class_or_type_or_tuple) should compare
using obj.__class__ when obj is an instance of a type
or a new-style class.

This is important for using weak references and other
kinds of proxy wrappers, where you want to pass a proxy
to some code, which might query its type using isinstance.

issubclass may need a similar treatment.

@steveazope steveazope mannequin closed this as completed Mar 20, 2002
@steveazope steveazope mannequin assigned gvanrossum Mar 20, 2002
@steveazope steveazope mannequin added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Mar 20, 2002
@steveazope steveazope mannequin closed this as completed Mar 20, 2002
@steveazope steveazope mannequin assigned gvanrossum Mar 20, 2002
@steveazope steveazope mannequin added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Mar 20, 2002
@loewis
Copy link
Mannequin

loewis mannequin commented Mar 21, 2002

Logged In: YES
user_id=21627

-1. That means that you can't use isinstance anymore to
determine whether something is a weak reference, or other
kind of proxy wrapper.

If you need a function that unwraps wrappers, write one
yourself.

@gvanrossum
Copy link
Member

Logged In: YES
user_id=6380

I give this a +1. To refute Martin's -1: The use case that
prompts this is passing a wrapper to wrapper-ignorant code.
This may be 3rd party code that you can't afford to make
wrapper-aware. If I pass you a wrapper to an X where you
expect an X, your isinstance(x, X) call should succeed.
Especially since x.__class__ already returns X. Also,
isinstance(x, X) succeeds if X is a classic class and x is a
wrapped X instance.

If you want to know if something is a wrapper, you have to
use type().

@loewis
Copy link
Mannequin

loewis mannequin commented Mar 21, 2002

Logged In: YES
user_id=21627

There has been a long-standing guarantee that 'type(o) is X'
implies 'isinstance(o, X)', or, more compact,
'isinstance(o,type(o))' for all objects o. In fact, people
have been advised to change the explicit test for type() to
isinstance calls. With the proposed change, this property
will be given up.

@steveazope
Copy link
Mannequin Author

steveazope mannequin commented Mar 21, 2002

Logged In: YES
user_id=492001

A new isinstance can maintain and extend the semantic Martin
describes.

Let's say object wl is a wrapped list:

from Zope.ContextWrapper import Wrapper

wl = Wrapper([])
assert isinstance(wl, list) is 1
assert isinstance(wl, Wrapper) is 1

So, your semantics are maintained. With the proposed change,
the property you describe need not be given up.

@steveazope
Copy link
Mannequin Author

steveazope mannequin commented Mar 21, 2002

Logged In: YES
user_id=492001

oops... please ignore my unsupported use of "is" to compare
small ints.

I meant:

from Zope.ContextWrapper import Wrapper

wl = Wrapper([])
assert isinstance(wl, list) == 1
assert isinstance(wl, Wrapper) == 1

@gvanrossum
Copy link
Member

Logged In: YES
user_id=6380

I'm not sure I like SteveA's suggestion of making
isinstance() respond both to the wrapper type and to the
wrapped type. Although there's a precedent:

>>> class C: pass # classic class
... 
>>> c = C()
>>> isinstance(c, C)
1
>>> import types
>>> isinstance(c, types.InstanceType)
1
>>> 

I'm also not sure I agree with Martin's assertion that
type(o) is X and isinstance(o, X) should always be
equivalent. Especially with new-style user-defined classes,
we could also require that o.__class__ == X and
isinstance(o, X) should be equivalent (modulo subclassing),
and that would require isinstance() to prefer __class__.

I guess we'll have to look at actual use cases of
isinstance() and wrappers (both weakrefs and Zope3's
transparent wrappers). My expectation is that, since
wrappers try hard to pretend to be the wrapped object,
extending this to the isinstance() test is more useful than
the stricter interpretation.

@gvanrossum
Copy link
Member

Logged In: YES
user_id=6380

OK, checked in. When X is a new-style class, isinstance(x,
X) is now defined as "issubclass(type(x), X) or
issubclass(x.__class__, X)". That seems a very reasonable
definition to me.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs)
Projects
None yet
Development

No branches or pull requests

1 participant