AttributeError with objects


test_attribute_error_w_variables and test_attribute_error_w_functions show that variables and functions in a module are attributes of the module.

Is an object in a module also an attribute of the module?

preview

I have these tests by the end of the chapter


open the project


test_attribute_error_w_object_attributes

RED: make it fail


  • I go back to the terminal where the tests are running

  • I add a test for object attributes to tests/test_attribute_error.py

    17def test_attribute_error_w_functions():
    18    src.attribute_error.function_00()
    19    src.attribute_error.function_01()
    20    src.attribute_error.function_02()
    21    src.attribute_error.function_03()
    22    src.attribute_error.function_04()
    23    src.attribute_error.function_05()
    24    src.attribute_error.function_06()
    25    src.attribute_error.function_07()
    26    src.attribute_error.function_08()
    27    src.attribute_error.function_09()
    28
    29
    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32
    33
    34# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'AnObject'
    

GREEN: make it pass


  • I open __init__.py from the attribute_error folder in the src folder

  • I add a function to src/attribute_error/__init__.py

    22def function_09(): return function_08()
    23
    24
    25def AnObject(): return function_09()
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'function' object
                    has no attribute 'attribute_00'
    
  • I add a variable for attribute_00 to the function

    25# def AnObject(): return function_09()
    26def AnObject():
    27
    28    attribute_00 = function_09()
    29    return function_09()
    

    the terminal still shows the same Exception because I cannot get to a variable inside a function from outside the function. The variable is only used inside the function when it runs.

  • I change AnObject from a function to an object

    25# def AnObject(): return function_09()
    26# def AnObject():
    27class AnObject(object):
    28
    29    attribute_00 = function_09()
    30    return function_09()
    

    the terminal is my friend, and shows SyntaxError

    E    return function_09()
    E    ^^^^^^^^^^^^^^^^^^^^
    E  SyntaxError: 'return' outside function
    

    because I cannot use a return statement outside a function.

  • I add SyntaxError to the list of Exceptions seen, in tests/test_attribute_error.py

    34# Exceptions seen
    35# AssertionError
    36# AttributeError
    37# NameError
    38# TypeError
    39# SyntaxError
    
  • I comment out the return statement from AnObject in src/attribute_error/__init__.py

    25# def AnObject(): return function_09()
    26# def AnObject():
    27class AnObject(object):
    28
    29    attribute_00 = function_09()
    30    # return function_09()
    
    • the test passes because attribute_00 is now an attribute/property of the AnObject object

    • AnObject is an attribute of the attribute_error module in the src folder

    • I can use attribute_00 from outside the file with src.attribute_error.AnObject.attribute_00 or src.attribute_error.AnObject().attribute_00

      src.attribute_error.AnObject.attribute_00
      src.attribute_error.AnObject().attribute_00
      └── src/
          └── attribute_error/
              └── __init__.py
                  └── class AnObject(object):
                      └── attribute_00 = function_09()
      

REFACTOR: make it better


  • I remove the commented lines

    22def function_09(): return function_08()
    23
    24
    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    
  • I add a line for src.attribute_error.AnObject().attribute_01 to tests/test_attribute_error.py

    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32    src.attribute_error.AnObject().attribute_01
    33
    34
    35# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'attribute_01'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_01 to the object definition in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    
    • the test passes because in this case it does not matter if I use the object (AnObject) or an instance of the class (AnObject()).

    • attribute_01 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can use it from outside the file with src.attribute_error.AnObject.attribute_01 or src.attribute_error.AnObject().attribute_01

      src.attribute_error.AnObject.attribute_01
      src.attribute_error.AnObject().attribute_01
      └── src/
          └── attribute_error/
              └── __init__.py
                  └── class AnObject(object):
                      └── attribute_01 = attribute_00
      
  • I add a line for src.attribute_error.AnObject.attribute_02 to tests/test_attribute_error.py

    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32    src.attribute_error.AnObject().attribute_01
    33    src.attribute_error.AnObject.attribute_02
    34
    35
    36# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AnObject'
                    has no attribute 'attribute_02'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_02 to the object definition in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    

    the test passes because attribute_02 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can use it from outside the file with src.attribute_error.AnObject.attribute_02 or src.attribute_error.AnObject().attribute_02

    src.attribute_error.AnObject.attribute_02
    src.attribute_error.AnObject().attribute_02
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── attribute_02 = attribute_01
    
  • I add a line for src.attribute_error.AnObject().attribute_03 to tests/test_attribute_error.py

    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32    src.attribute_error.AnObject().attribute_01
    33    src.attribute_error.AnObject.attribute_02
    34    src.attribute_error.AnObject().attribute_03
    35
    36
    37# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'attribute_03'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_03 to the object definition in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    

    the test passes because attribute_03 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can use it from outside the file with src.attribute_error.AnObject.attribute_03 or src.attribute_error.AnObject().attribute_03

    src.attribute_error.AnObject.attribute_03
    src.attribute_error.AnObject().attribute_03
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── attribute_03 = attribute_02
    
  • I add a line for src.attribute_error.AnObject.attribute_04 to tests/test_attribute_error.py

    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32    src.attribute_error.AnObject().attribute_01
    33    src.attribute_error.AnObject.attribute_02
    34    src.attribute_error.AnObject().attribute_03
    35    src.attribute_error.AnObject.attribute_04
    36
    37
    38# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AnObject'
                    has no attribute 'attribute_04'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_04 to the object definition in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    31    attribute_04 = attribute_03
    

    the test passes because attribute_04 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can use it from outside the file with src.attribute_error.AnObject.attribute_04 or src.attribute_error.AnObject().attribute_04

    src.attribute_error.AnObject.attribute_04
    src.attribute_error.AnObject().attribute_04
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── attribute_04 = attribute_03
    
  • I add a line for src.attribute_error.AnObject().attribute_05 to tests/test_attribute_error.py

    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32    src.attribute_error.AnObject().attribute_01
    33    src.attribute_error.AnObject.attribute_02
    34    src.attribute_error.AnObject().attribute_03
    35    src.attribute_error.AnObject.attribute_04
    36    src.attribute_error.AnObject().attribute_05
    37
    38
    39# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'attribute_05'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_05 to the object definition in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    31    attribute_04 = attribute_03
    32    attribute_05 = attribute_04
    

    the test passes because attribute_05 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can use it from outside the file with src.attribute_error.AnObject.attribute_05 or src.attribute_error.AnObject().attribute_05

    src.attribute_error.AnObject.attribute_05
    src.attribute_error.AnObject().attribute_05
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── attribute_05 = attribute_04
    
  • I add a line for src.attribute_error.AnObject().attribute_06 to tests/test_attribute_error.py

    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32    src.attribute_error.AnObject().attribute_01
    33    src.attribute_error.AnObject.attribute_02
    34    src.attribute_error.AnObject().attribute_03
    35    src.attribute_error.AnObject.attribute_04
    36    src.attribute_error.AnObject().attribute_05
    37    src.attribute_error.AnObject().attribute_06
    38
    39
    40# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'attribute_06'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_06 to the object definition in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    31    attribute_04 = attribute_03
    32    attribute_05 = attribute_04
    33    attribute_06 = attribute_05
    

    the test passes because attribute_06 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can use it from outside the file with src.attribute_error.AnObject.attribute_06 or src.attribute_error.AnObject().attribute_06

    src.attribute_error.AnObject.attribute_06
    src.attribute_error.AnObject().attribute_06
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── attribute_06 = attribute_05
    
  • I add a line for src.attribute_error.AnObject.attribute_07 to tests/test_attribute_error.py

    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32    src.attribute_error.AnObject().attribute_01
    33    src.attribute_error.AnObject.attribute_02
    34    src.attribute_error.AnObject().attribute_03
    35    src.attribute_error.AnObject.attribute_04
    36    src.attribute_error.AnObject().attribute_05
    37    src.attribute_error.AnObject().attribute_06
    38    src.attribute_error.AnObject.attribute_07
    39
    40
    41# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AnObject'
                    has no attribute 'attribute_07'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_07 to the object definition in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    31    attribute_04 = attribute_03
    32    attribute_05 = attribute_04
    33    attribute_06 = attribute_05
    34    attribute_07 = attribute_06
    

    the test passes because attribute_07 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can use it from outside the file with src.attribute_error.AnObject.attribute_07 or src.attribute_error.AnObject().attribute_07

    src.attribute_error.AnObject.attribute_07
    src.attribute_error.AnObject().attribute_07
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── attribute_07 = attribute_06
    
  • I add a line for src.attribute_error.AnObject.attribute_08 to tests/test_attribute_error.py

    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32    src.attribute_error.AnObject().attribute_01
    33    src.attribute_error.AnObject.attribute_02
    34    src.attribute_error.AnObject().attribute_03
    35    src.attribute_error.AnObject.attribute_04
    36    src.attribute_error.AnObject().attribute_05
    37    src.attribute_error.AnObject().attribute_06
    38    src.attribute_error.AnObject.attribute_07
    39    src.attribute_error.AnObject.attribute_08
    40
    41
    42# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AnObject'
                    has no attribute 'attribute_08'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_08 to the object definition in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    31    attribute_04 = attribute_03
    32    attribute_05 = attribute_04
    33    attribute_06 = attribute_05
    34    attribute_07 = attribute_06
    35    attribute_08 = attribute_07
    

    the test passes because attribute_08 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can use it from outside the file with src.attribute_error.AnObject.attribute_08 or src.attribute_error.AnObject().attribute_08

    src.attribute_error.AnObject.attribute_08
    src.attribute_error.AnObject().attribute_08
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── attribute_08 = attribute_07
    
  • I add a line for src.attribute_error.AnObject().attribute_09 to tests/test_attribute_error.py

    30def test_attribute_error_w_object_attributes():
    31    src.attribute_error.AnObject.attribute_00
    32    src.attribute_error.AnObject().attribute_01
    33    src.attribute_error.AnObject.attribute_02
    34    src.attribute_error.AnObject().attribute_03
    35    src.attribute_error.AnObject.attribute_04
    36    src.attribute_error.AnObject().attribute_05
    37    src.attribute_error.AnObject().attribute_06
    38    src.attribute_error.AnObject.attribute_07
    39    src.attribute_error.AnObject.attribute_08
    40    src.attribute_error.AnObject().attribute_09
    41
    42
    43# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'attribute_09'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_09 to the object definition in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    31    attribute_04 = attribute_03
    32    attribute_05 = attribute_04
    33    attribute_06 = attribute_05
    34    attribute_07 = attribute_06
    35    attribute_08 = attribute_07
    36    attribute_09 = attribute_08
    

    the test passes because attribute_09 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can use it from outside the file with src.attribute_error.AnObject.attribute_09 or src.attribute_error.AnObject().attribute_09

    src.attribute_error.AnObject.attribute_09
    src.attribute_error.AnObject().attribute_09
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── attribute_09 = attribute_08
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_attribute_error_w_object_attributes'
    
  • A variable in an object is an attribute of the class

  • A class in a module is an attribute of the module

  • A function in a module is an attribute of the module

  • A variable in a module is an attribute of the module


test_attribute_error_w_object_methods

The tests show that variables, functions and objects in a module are attributes of the module, and variables in an object are attributes of the class.

Methods of a class are also attributes of the class.


RED: make it fail


  • I go back to the terminal where the tests are running

  • I add a test for methods to tests/test_attribute_error.py

    40    src.attribute_error.AnObject().attribute_09
    41
    42
    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject.method_00()
    45
    46
    47# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AnObject'
                    has no attribute 'method_00'
    

GREEN: make it pass


  • I add the name to AnObject and point it to attribute_09, in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    31    attribute_04 = attribute_03
    32    attribute_05 = attribute_04
    33    attribute_06 = attribute_05
    34    attribute_07 = attribute_06
    35    attribute_08 = attribute_07
    36    attribute_09 = attribute_08
    37
    38    method_00 = attribute_09
    

    the terminal is my friend, and shows TypeError

    TypeError: 'NoneType' object is not callable
    

    because method_00 is attribute_09, attribute_09 is None, and I cannot call None like a function.

  • I use the def keyword to change it from a variable (attribute) to a method

    36    attribute_09 = attribute_08
    37
    38    # method_00 = attribute_09
    39    def method_00(): return attribute_09
    

    the terminal is my friend, and shows NameError

    NameError: name 'attribute_09' is not defined
    

    because there is nothing inside method_00 named attribute_09 and it cannot get to attribute_09 of AnObject, yet.

  • I add self. before the name to reference the object attribute

    38    # method_00 = attribute_09
    39    # def method_00(): return attribute_09
    40    def method_00(): return self.attribute_09
    

    the terminal is my friend, and shows NameError

    NameError: name 'self' is not defined
    
  • I add self to the parentheses of method_00

    38    # method_00 = attribute_09
    39    # def method_00(): return attribute_09
    40    # def method_00(): return self.attribute_09
    41    def method_00(self): return self.attribute_09
    

    the terminal is my friend, and shows TypeError

    TypeError: AnObject.method_00() missing
               1 required positional argument: 'self'
    

    because I called the method with the object not an instance of the class.

  • I use an instance of the class to call the method in tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    # src.attribute_error.AnObject.method_00()
    45    src.attribute_error.AnObject().method_00()
    46
    47
    48# Exceptions seen
    
    src.attribute_error.AnObject().method_00
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── def method_00(self):
                        └── return self.attribute_09
    

REFACTOR: make it better


  • I remove the commented lines from src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    31    attribute_04 = attribute_03
    32    attribute_05 = attribute_04
    33    attribute_06 = attribute_05
    34    attribute_07 = attribute_06
    35    attribute_08 = attribute_07
    36    attribute_09 = attribute_08
    37
    38    def method_00(self): return self.attribute_09
    
  • I remove the commented line from tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45
    46
    47# Exceptions seen
    
  • You know the “drill”, I add a call to src.attribute_error.AnObject().method_01

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45    src.attribute_error.AnObject().method_01()
    46
    47
    48# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'method_01'.
                    Did you mean: 'method_00'?
    
  • I add the method to the definition of AnObject in src/attribute_error/__init__.py

    38    def method_00(self): return self.attribute_09
    39    def method_01(self): return self.method_00()
    

    the test passes because method_01 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can call it from outside the file with src.attribute_error.AnObject().method_01()

    src.attribute_error.AnObject().method_01
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── def method_01(self):
                        └── return self.method_00()
    
  • I add a call to src.attribute_error.AnObject().method_02 from tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45    src.attribute_error.AnObject().method_01()
    46    src.attribute_error.AnObject().method_02()
    47
    48
    49# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'method_02'.
                    Did you mean: 'method_00'?
    
  • I add the method to the definition of AnObject in src/attribute_error/__init__.py

    38    def method_00(self): return self.attribute_09
    39    def method_01(self): return self.method_00()
    40    def method_02(self): return self.method_01()
    

    the test passes because method_02 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can call it from outside the file with src.attribute_error.AnObject().method_02()

    src.attribute_error.AnObject().method_02
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── def method_02(self):
                        └── return self.method_01()
    
  • I add a call to src.attribute_error.AnObject().method_03 from tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45    src.attribute_error.AnObject().method_01()
    46    src.attribute_error.AnObject().method_02()
    47    src.attribute_error.AnObject().method_03()
    48
    49
    50# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'method_03'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_03 to the definition of AnObject in src/attribute_error/__init__.py

    38    def method_00(self): return self.attribute_09
    39    def method_01(self): return self.method_00()
    40    def method_02(self): return self.method_01()
    41    def method_03(self): return self.method_02()
    

    the test passes because method_03 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can call it from outside the file with src.attribute_error.AnObject().method_03()

    src.attribute_error.AnObject().method_03
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── def method_03(self):
                        └── return self.method_02()
    
  • I add a call to src.attribute_error.AnObject().method_04 from tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45    src.attribute_error.AnObject().method_01()
    46    src.attribute_error.AnObject().method_02()
    47    src.attribute_error.AnObject().method_03()
    48    src.attribute_error.AnObject().method_04()
    49
    50
    51# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'method_04'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_04 to the definition of AnObject in src/attribute_error/__init__.py

    38    def method_00(self): return self.attribute_09
    39    def method_01(self): return self.method_00()
    40    def method_02(self): return self.method_01()
    41    def method_03(self): return self.method_02()
    42    def method_04(self): return self.method_03()
    

    the test passes because method_04 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can call it from outside the file with src.attribute_error.AnObject().method_04()

    src.attribute_error.AnObject().method_04
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── def method_04(self): return self.method_03()
    
  • I add a call to src.attribute_error.AnObject().method_05 from tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45    src.attribute_error.AnObject().method_01()
    46    src.attribute_error.AnObject().method_02()
    47    src.attribute_error.AnObject().method_03()
    48    src.attribute_error.AnObject().method_04()
    49    src.attribute_error.AnObject().method_05()
    50
    51
    52# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'method_05'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_05 to the definition of AnObject in src/attribute_error/__init__.py

    38    def method_00(self): return self.attribute_09
    39    def method_01(self): return self.method_00()
    40    def method_02(self): return self.method_01()
    41    def method_03(self): return self.method_02()
    42    def method_04(self): return self.method_03()
    43    def method_05(self): return self.method_04()
    

    the test passes.

  • I add a call to src.attribute_error.AnObject().method_06 from tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45    src.attribute_error.AnObject().method_01()
    46    src.attribute_error.AnObject().method_02()
    47    src.attribute_error.AnObject().method_03()
    48    src.attribute_error.AnObject().method_04()
    49    src.attribute_error.AnObject().method_05()
    50    src.attribute_error.AnObject().method_06()
    51
    52
    53# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'method_06'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_06 to the definition of AnObject in src/attribute_error/__init__.py

    38    def method_00(self): return self.attribute_09
    39    def method_01(self): return self.method_00()
    40    def method_02(self): return self.method_01()
    41    def method_03(self): return self.method_02()
    42    def method_04(self): return self.method_03()
    43    def method_05(self): return self.method_04()
    44    def method_06(self): return self.method_05()
    

    the test passes.

  • I add a call to src.attribute_error.AnObject().method_07 from tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45    src.attribute_error.AnObject().method_01()
    46    src.attribute_error.AnObject().method_02()
    47    src.attribute_error.AnObject().method_03()
    48    src.attribute_error.AnObject().method_04()
    49    src.attribute_error.AnObject().method_05()
    50    src.attribute_error.AnObject().method_06()
    51    src.attribute_error.AnObject().method_07()
    52
    53
    54# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'method_07'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_07 to the definition of AnObject in src/attribute_error/__init__.py

    38    def method_00(self): return self.attribute_09
    39    def method_01(self): return self.method_00()
    40    def method_02(self): return self.method_01()
    41    def method_03(self): return self.method_02()
    42    def method_04(self): return self.method_03()
    43    def method_05(self): return self.method_04()
    44    def method_06(self): return self.method_05()
    45    def method_07(self): return self.method_06()
    

    the test passes.

  • I add a call to src.attribute_error.AnObject().method_08 from tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45    src.attribute_error.AnObject().method_01()
    46    src.attribute_error.AnObject().method_02()
    47    src.attribute_error.AnObject().method_03()
    48    src.attribute_error.AnObject().method_04()
    49    src.attribute_error.AnObject().method_05()
    50    src.attribute_error.AnObject().method_06()
    51    src.attribute_error.AnObject().method_07()
    52    src.attribute_error.AnObject().method_08()
    53
    54
    55# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'method_08'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_08 to the definition of AnObject in src/attribute_error/__init__.py

    38    def method_00(self): return self.attribute_09
    39    def method_01(self): return self.method_00()
    40    def method_02(self): return self.method_01()
    41    def method_03(self): return self.method_02()
    42    def method_04(self): return self.method_03()
    43    def method_05(self): return self.method_04()
    44    def method_06(self): return self.method_05()
    45    def method_07(self): return self.method_06()
    46    def method_08(self): return self.method_07()
    

    the test passes.

  • I add a call to src.attribute_error.AnObject().method_09 from tests/test_attribute_error.py

    43def test_attribute_error_w_object_methods():
    44    src.attribute_error.AnObject().method_00()
    45    src.attribute_error.AnObject().method_01()
    46    src.attribute_error.AnObject().method_02()
    47    src.attribute_error.AnObject().method_03()
    48    src.attribute_error.AnObject().method_04()
    49    src.attribute_error.AnObject().method_05()
    50    src.attribute_error.AnObject().method_06()
    51    src.attribute_error.AnObject().method_07()
    52    src.attribute_error.AnObject().method_08()
    53    src.attribute_error.AnObject().method_09()
    54
    55
    56# Exceptions seen
    57# AssertionError
    58# AttributeError
    59# NameError
    60# TypeError
    61# SyntaxError
    

    the terminal is my friend, and shows AttributeError

    AttributeError: 'AnObject' object
                    has no attribute 'method_09'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_09 to the definition of AnObject in src/attribute_error/__init__.py

    25class AnObject(object):
    26
    27    attribute_00 = function_09()
    28    attribute_01 = attribute_00
    29    attribute_02 = attribute_01
    30    attribute_03 = attribute_02
    31    attribute_04 = attribute_03
    32    attribute_05 = attribute_04
    33    attribute_06 = attribute_05
    34    attribute_07 = attribute_06
    35    attribute_08 = attribute_07
    36    attribute_09 = attribute_08
    
    38    def method_00(self): return self.attribute_09
    39    def method_01(self): return self.method_00()
    40    def method_02(self): return self.method_01()
    41    def method_03(self): return self.method_02()
    42    def method_04(self): return self.method_03()
    43    def method_05(self): return self.method_04()
    44    def method_06(self): return self.method_05()
    45    def method_07(self): return self.method_06()
    46    def method_08(self): return self.method_07()
    47    def method_09(self): return self.method_08()
    

    the test passes because method_09 is now an attribute of AnObject in src/attribute_error/__init__.py, and I can call it from outside the file with src.attribute_error.AnObject().method_09()

    src.attribute_error.AnObject().method_09
    └── src/
        └── attribute_error/
            └── __init__.py
                └── class AnObject(object):
                    └── def method_09(self):
                        └── return self.method_08()
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_attribute_error_w_object_methods'
    

A function in an object is an attribute of the class and is called a method


close the project

  • I close src/attribute_error/__init__.py and tests/test_attribute_error.py

  • I click in the terminal where the tests are running

  • I use q on the keyboard to leave the tests. The terminal goes back to the command line.

  • I change directory to the parent of attribute_error

    cd ..
    

    the terminal shows

    .../pumping_python
    

    I am back in the pumping_python directory.


review

All the tests I have run for AttributeError show that

I still have the problem that the tests all show the correct way to use attributes I made in src/attribute_error/__init__.py. If someone reads the file or runs it, there is no way for them to know how the code relates to AttributeError unless they go through the process with me, there has to be a better way.


code from the chapter

Do you want to see all the CODE I typed in this chapter?


what is next?

Would you like to test TypeError with objects?


rate pumping python

If this has been a 7 star experience for you, please CLICK HERE to leave a 5 star review of pumping python. It helps other people get into the book too.