Skip to content

isinstance(anything, MetaclassThatDefinesInstancecheck) raises instead of returning False #46578

Closed

Description

@jyasskin
mannequin
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']

    Activity

    1. jyasskin commented on Mar 17, 2008

      jyasskinmannequin
      MannequinAuthor
      >>> 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)
    2. added
      interpreter-core(Objects, Python, Grammar, and Parser dirs)
      type-bugAn unexpected behavior, bug, or error
      on Mar 17, 2008
    3. werneck commented on May 2, 2008

      werneckmannequin
      Mannequin

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

    4. werneck commented on May 3, 2008

      werneckmannequin
      Mannequin

      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

    5. mato2000 commented on Jun 21, 2008

      mato2000mannequin
      Mannequin

      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
    6. zanella commented on Jun 30, 2008

      zanellamannequin
      Mannequin

      So..., could this issue be closed ?

    7. mato2000 commented on Jun 30, 2008

      mato2000mannequin
      Mannequin

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

    8. jyasskin commented on Jun 30, 2008

      jyasskinmannequin
      MannequinAuthor

      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.

    9. amauryfa commented on Jun 30, 2008

      @amauryfa
      Contributor

      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.

    10. devdanzin commented on May 13, 2009

      devdanzinmannequin
      Mannequin

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

    11. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      interpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions