Search code examples
pythonpython-3.xunit-testingtypeerrorsetter

Setter not throwing errors


I have a Node class that I'd like to make sure only accepts other Node object as its child, but the TypeError is never raised in my unit tests. I'm using python 3.

Class

class Node:

    def __init__(self, data):
        self._child = None
        self._data = data

    @property
    def child(self):
        return self._child

    @child.setter
    def child(self, child):
        if not isinstance(child, Node):
            raise TypeError(f"Children must be of type Node, not {type(child)}.")
        self._child = child

    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, data):
        self._data = data

Test

def test_node_child_error():
    node = Node(1)
    with pytest.raises(TypeError):
        node.child = 2

The unit test returns Failed: DID NOT RAISE <class 'TypeError'> and when I try and log the new value to the terminal inside of the setter it says that child is <class 'NoneType'>, but the value does change according to the Node object itself when I log it afterwards.

I have been trying to use the PyCharm debugger to get a closer look, but unfortunately I used the same class name in another file as a class used in the debugger so it doesn't work anymore.


Solution

  • I found the issue but would appreciate some explanation as to why/how this fixes it. Obviously the issue was coming from the setter getting a None type every time it is called so I edited the setter to be as follows.

    @child.setter
    def child(self, child):
        if not isinstance(child, Node) and child is not None:
            raise TypeError(f"Children must be of type Node, not {type(child)}.")
        self._child = child
    

    Not only does this fix my test cases, but now when I try to purposely throw the error I get the correct error message of TypeError: Children must be of type Node, not <class 'int'>. instead of TypeError: Children must be of type Node, not <class 'None'>..