Python Forum
Unexpected expected type error result - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Unexpected expected type error result (/thread-16025.html)



Unexpected expected type error result - MartinMaker - Feb-11-2019

# creating a new kind of class or instance attribute

class Integer:
    def __init__(self, name):
        self.name = name

    def __get__(self, instance, cls):
        if instance is None:
            return self
        else:
            return instance.__dict__[self.name]

    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise TypeError('expected an int')
        instance.__dict__[self.name] = value


    def __delete__(self, instance):
        del instance.__dict__[self]


class Point:
    x = Integer('x')
    y = Integer('y')
    def __init__(self, x, y):
        self.x = x
        self.y = y


p = Point(12, 3)
my_int = Integer(1)
print('myint:   {}   {}'.format(my_int, my_int.name))
print('{}   {}'.format(p.x, p.y))


my_int2 = Integer('1')
print('myint2:  {}   {}'.format(my_int2, my_int2.name))
# p2 = Point('1', 3)
my_int2 = Integer('1')
does not produce the expected type error
while uncommenting p2 does raise the expected error
TypeError: expected an int
Wall


RE: Unexpected expected type error result - micseydel - Feb-16-2019

I wasn't familiar before with these magic methods but here's what I learned...

You've constructed Integer such that in Point, when self.x and self.y are assigned (or "__set__"), that the TypeError-raising code gets called. Merely constructing an integer directly only invokes its initializer, not its __set__ method. So this code appears to be working as it ought to. (I'm not as sure about __get__ or __delete__, but that's not what your question seems to be about.)