2

Why does this happen?

class IsInstanceScrewer(object):
    def __init__(self, value):
        self.value = value

    def __getattribute__(self, name):
        if name in ('value',):
            return object.__getattribute__(self, name)
        value = object.__getattribute__(self, 'value')
        return object.__getattribute__(value, name)

isinstance(IsInstanceScrewer(False), bool) #True
isinstance(IsInstanceScrewer([1, 2, 3]), list) #True

The class is definitely not an instance of bool, even though it attempts to wrap it.

Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • Note that you need to change `('value')` to `('value',)` (with a comma), otherwise you have not created a tuple and `if name in ('value')` will be true if `name` is a substring of "value". – BrenBarn Jan 25 '13 at 19:44
  • @BrenBarn: good catch. i used to have more items there in my initial example but reduced them to make it simpler and introduced a bug in the mean-time – Claudiu Jan 25 '13 at 19:50

1 Answers1

2

__getattribute__ is returning the __class__ of the wrapped value instead of its own __class__:

>>> class IsInstanceScrewer(object):
    def __init__(self, value):
        self.value = value

    def __getattribute__(self, name):
        print name
        if name in ('value',):
            return object.__getattribute__(self, name)
        value = object.__getattribute__(self, 'value')
        return object.__getattribute__(value, name)

>>> isinstance(IsInstanceScrewer(False), bool)
__class__
True
>>> isinstance(IsInstanceScrewer([1, 2, 3]), list)
__class__
True

This may be desired behavior or not depending on what you're doing.

Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • Beat me to it. I was just about to post this. (but you did have a head start ;-) – mgilson Jan 25 '13 at 19:50
  • As a side note, rather than a whole-sale overwriting of all attributes, sometimes it's a little nicer to define `__getattr__` which is only invoked if python fails to find the attribute through normal means. – mgilson Jan 25 '13 at 19:52