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(anything, MetaclassThatDefinesInstancecheck) raises instead of returning False #46578

Closed
jyasskin mannequin opened this issue Mar 17, 2008 · 9 comments
Closed
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@jyasskin
Copy link
Mannequin

jyasskin mannequin commented Mar 17, 2008

BPO 2325
Nosy @amauryfa, @devdanzin
Files
  • instancecheck.patch: patch for 2.6
  • 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 = None
    closed_at = <Date 2009-05-13.22:28:50.758>
    created_at = <Date 2008-03-17.16:45:06.118>
    labels = ['interpreter-core', 'type-bug']
    title = 'isinstance(anything, MetaclassThatDefinesInstancecheck) raises instead of returning False'
    updated_at = <Date 2009-05-13.22:28:50.756>
    user = 'https://bugs.python.org/jyasskin'

    bugs.python.org fields:

    activity = <Date 2009-05-13.22:28:50.756>
    actor = 'ajaksu2'
    assignee = 'none'
    closed = True
    closed_date = <Date 2009-05-13.22:28:50.758>
    closer = 'ajaksu2'
    components = ['Interpreter Core']
    creation = <Date 2008-03-17.16:45:06.118>
    creator = 'jyasskin'
    dependencies = []
    files = ['10783']
    hgrepos = []
    issue_num = 2325
    keywords = ['patch']
    message_count = 9.0
    messages = ['63671', '66129', '66134', '68532', '68985', '68987', '68990', '69005', '87718']
    nosy_count = 6.0
    nosy_names = ['amaury.forgeotdarc', 'ajaksu2', 'jyasskin', 'zanella', 'werneck', 'mato2000']
    pr_nums = []
    priority = 'normal'
    resolution = 'out of date'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue2325'
    versions = ['Python 2.6', 'Python 3.0']

    @jyasskin
    Copy link
    Mannequin Author

    jyasskin mannequin commented Mar 17, 2008

    >>> class Meta(type):
    ...   def __instancecheck__(self, other):
    ...     return False
    >>> isinstance(3, Meta)

    In 2.6, this results in:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    RuntimeError: maximum recursion depth exceeded while calling a Python object
    (That's a recursion in C, through PyObject_IsInstance and
    instancemethod_call)

    In 3.0, I get:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: __instancecheck__() takes exactly 2 positional arguments (1
    given)

    @jyasskin jyasskin mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels Mar 17, 2008
    @werneck
    Copy link
    Mannequin

    werneck mannequin commented May 2, 2008

    In 3.0 it happens with any class. Just the cls argument missing on the
    call to instancecheck.

    @werneck
    Copy link
    Mannequin

    werneck mannequin commented May 3, 2008

    Seems like that's the wrong usage and the PEP-3119 notices that it's
    hard to get the right semantics. To use it that way you need to define
    the methods as a classmethod().

    http://www.python.org/dev/peps/pep-3119/#one-trick-ponies

    @mato2000
    Copy link
    Mannequin

    mato2000 mannequin commented Jun 21, 2008

    This is not a bug. Function __instancecheck__ should be a classmethod.

    >>> class Meta(type):
    ...     @classmethod
    ...     def __instancecheck__(self, other):
    ...             return False
    ... 
    >>> isinstance(3, Meta)
    False

    @zanella
    Copy link
    Mannequin

    zanella mannequin commented Jun 30, 2008

    So..., could this issue be closed ?

    @mato2000
    Copy link
    Mannequin

    mato2000 mannequin commented Jun 30, 2008

    Yes, it should be. I don't have permissions to.

    @jyasskin
    Copy link
    Mannequin Author

    jyasskin mannequin commented Jun 30, 2008

    I don't think so. It wouldn't be a bug if I wrote:

    >>> class Meta(type):
    ...   def __instancecheck__(self, other):
    ...     return True
    >>> isinstance(3, Meta)
    ... False

    but it is a bug that the isinstance call raises an exception. If recent
    builds no longer raise an exception, then the bug should be closed.

    You guys also seem to have missed that the examples in PEP-3119 in fact
    define __instancecheck__ as a normal method on a metaclass (which makes
    it a classmethod on classes derived from that metaclass) instead of as a
    classmethod on a metaclass.

    @jyasskin jyasskin mannequin reopened this Jun 30, 2008
    @jyasskin jyasskin mannequin removed the invalid label Jun 30, 2008
    @amauryfa
    Copy link
    Member

    I think the best is to ignore __instancecheck__ when
    "cls.__instancecheck__" is returned as an unbound method. In this case,
    we try "type(cls).__instancecheck__" instead.

    Here is a patch along this idea.
    I had to disable a test named "Evil", because in this case isinstance()
    simply falls back to the original algorithm.

    I don't know if this is applicable to 3.0: unbound methods don't exist
    any more.

    @devdanzin
    Copy link
    Mannequin

    devdanzin mannequin commented May 13, 2009

    This now works correctly (returns False) in release26-maint, trunk and py3k.

    @devdanzin devdanzin mannequin closed this as completed May 13, 2009
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 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) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants