-1

I am having trouble getting a test to pass. When I run the code it seems to work find, but in pytest it fails:

desk.py

class Dimension:
    x = 0
    y = 0
    z = 0
    
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

class Desk:
    def __init__(self, dimension):
        self.dimension = dimension

    @property
    def dimension(self):
        return self.__dimension

    @dimension.setter
    def dimension(self, d):
        s = d.split(".")
        self.__dimension = Dimension(int(s[0]), int(s[1]), int(s[2]))

    @property
    def is_large(self):
        if self.dimension.x > 100:
             return True
        return False

test_desk.py

...
def test_is_large():
    desk = Desk("5.5.5")
    assert desk.is_large == False
...

I get AttributeError: 'str' object has no attribute 'x'

If I change to getter and setter methods it works find, but I would like to use decorators.

UPDATE: I used python3 -m pytest to run pytest using python3 and it works fine

DoubleOseven
  • 271
  • 2
  • 13
  • 1
    If you're using `setter` and `getter`, you should stick with them. When you call `self.dimension.x` from a class function, you're accessing the `dimension` object defined in the `__init__`, which is a string, that doesn't have the attribute `x`; hence the error message. – crissal Jun 12 '21 at 10:07
  • 1
    should the class Dimension accept the x, y, z, arguments? – dandiez Jun 12 '21 at 10:18
  • @crissal Not sure why you think that. It indeed calls the setter, as expected. The problem is elsewhere. – Ami Tavory Jun 12 '21 at 10:23

1 Answers1

1

It's the double underscore of self.__dimension. Read this: What is the difference in python attributes with underscore in front and back

And this: How to access "__" (double underscore) variables in methods added to a class

Change self.__dimension to self._dimension and it will make.

EDIT: Not the underscore. Your code works perfectly in Python3. In Python2 I made it work this way:

class Dimension:
    x = 0
    y = 0
    z = 0
    def __init__(self, x, y, z):
        self.x = 0
        self.y = 0
        self.z = 0

class Desk:
    def __init__(self, dimension):
        s = dimension.split(".")
        self.__dimension = Dimension(int(s[0]), int(s[1]), int(s[2]))
    @property
    def dimension(self):
        return self.__dimension
    @dimension.setter
    def dimension(self, d):
        s = d.split(".")
        self.__dimension = Dimension(int(s[0]), int(s[1]), int(s[2]))
    @property
    def is_large(self):
        if self.dimension.x > 100:
             return True
        return False