AttributeError with classes


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 a class in a module also an attribute of the module?

preview

I have these tests by the end of the chapter

 1import src.attribute_error
 2
 3
 4def test_attribute_error_w_variables():
 5    src.attribute_error.variable_00
 6    src.attribute_error.variable_01
 7    src.attribute_error.variable_02
 8    src.attribute_error.variable_03
 9    src.attribute_error.variable_04
10    src.attribute_error.variable_05
11    src.attribute_error.variable_06
12    src.attribute_error.variable_07
13    src.attribute_error.variable_08
14    src.attribute_error.variable_09
15
16
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_class_attributes():
31    src.attribute_error.AClass.attribute_00
32    src.attribute_error.AClass().attribute_01
33    src.attribute_error.AClass.attribute_02
34    src.attribute_error.AClass().attribute_03
35    src.attribute_error.AClass.attribute_04
36    src.attribute_error.AClass().attribute_05
37    src.attribute_error.AClass().attribute_06
38    src.attribute_error.AClass.attribute_07
39    src.attribute_error.AClass.attribute_08
40    src.attribute_error.AClass().attribute_09
41
42
43def test_attribute_error_w_class_methods():
44    src.attribute_error.AClass().method_00()
45    src.attribute_error.AClass().method_01()
46    src.attribute_error.AClass().method_02()
47    src.attribute_error.AClass().method_03()
48    src.attribute_error.AClass().method_04()
49    src.attribute_error.AClass().method_05()
50    src.attribute_error.AClass().method_06()
51    src.attribute_error.AClass().method_07()
52    src.attribute_error.AClass().method_08()
53    src.attribute_error.AClass().method_09()
54
55
56# Exceptions seen
57# AssertionError
58# ModuleNotFoundError
59# AttributeError
60# NameError
61# TypeError
62# SyntaxError

open the project


test_attribute_error_w_class_attributes


RED: make it fail


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

  • I add a test for class attributes to 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_class_attributes():
    31    src.attribute_error.AClass.attribute_00
    32
    33
    34# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

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

GREEN: make it pass


  • I open attribute_error.py

  • I add a function to attribute_error.py

    22def function_09(): return function_08()
    23
    24
    25def AClass(): 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 AClass(): return function_09()
    26def AClass():
    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 AClass from a function to a class

    25# def AClass(): return function_09()
    26# def AClass():
    27class AClass(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 test_attribute_error.py

    34# Exceptions seen
    35# AssertionError
    36# ModuleNotFoundError
    37# AttributeError
    38# NameError
    39# TypeError
    40# SyntaxError
    
  • I comment out the return statement from AClass in attribute_error.py

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

    • AClass is an attribute of the attribute_error.py module in the src folder

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

      src.attribute_error.AClass.attribute_00
      src.attribute_error.AClass().attribute_00
      src
      └── attribute_error.py
          └── class AClass(object):
              └── attribute_00 = function_09()
      

REFACTOR: make it better


  • I remove the commented lines

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'attribute_01'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_01 to the class definition in attribute_error.py

    25class AClass(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 class (AClass) or an instance of the class (AClass()).

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

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

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

    the terminal is my friend, and shows AttributeError

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

    25class AClass(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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass.attribute_02 or src.attribute_error.AClass().attribute_02

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'attribute_03'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_03 to the class definition in attribute_error.py

    25class AClass(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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass.attribute_03 or src.attribute_error.AClass().attribute_03

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

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

    the terminal is my friend, and shows AttributeError

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

    25class AClass(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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass.attribute_04 or src.attribute_error.AClass().attribute_04

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'attribute_05'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_05 to the class definition in attribute_error.py

    25class AClass(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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass.attribute_05 or src.attribute_error.AClass().attribute_05

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'attribute_06'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_06 to the class definition in attribute_error.py

    25class AClass(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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass.attribute_06 or src.attribute_error.AClass().attribute_06

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

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

    the terminal is my friend, and shows AttributeError

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

    25class AClass(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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass.attribute_07 or src.attribute_error.AClass().attribute_07

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

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

    the terminal is my friend, and shows AttributeError

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

    25class AClass(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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass.attribute_08 or src.attribute_error.AClass().attribute_08

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'attribute_09'.
                    Did you mean: 'attribute_00'?
    
  • I add attribute_09 to the class definition in attribute_error.py

    25class AClass(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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass.attribute_09 or src.attribute_error.AClass().attribute_09

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

    git commit -am \
    'add test_attribute_error_w_class_attributes'
    
  • A variable in a class 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_class_methods

The tests show that variables, functions and classes in a module are attributes of the module, and variables in a class 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 test_attribute_error.py

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

    the terminal is my friend, and shows AttributeError

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

GREEN: make it pass


  • I add the name to AClass and point it to attribute_09, in attribute_error.py

    25class AClass(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 = None
    

    the terminal is my friend, and shows TypeError

    TypeError: 'NoneType' object is not callable
    

    because method_00 points to 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 AClass, yet.

  • I add self. before the name to reference the class 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: AClass().method_00() missing
               1 required positional argument: 'self'
    

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

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

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

REFACTOR: make it better


  • I remove the commented lines from attribute_error.py

    25class AClass(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 test_attribute_error.py

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'method_01'.
                    Did you mean: 'method_00'?
    
  • I add the method to the definition of AClass in attribute_error.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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass().method_01()

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'method_02'.
                    Did you mean: 'method_00'?
    
  • I add the method to the definition of AClass in attribute_error.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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass().method_02()

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'method_03'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_03 to the definition of AClass in attribute_error.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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass().method_03()

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'method_04'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_04 to the definition of AClass in attribute_error.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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass().method_04()

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

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'method_05'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_05 to the definition of AClass in attribute_error.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.AClass().method_06 from test_attribute_error.py

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'method_06'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_06 to the definition of AClass in attribute_error.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.AClass().method_07 from test_attribute_error.py

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'method_07'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_07 to the definition of AClass in attribute_error.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.AClass().method_08 from test_attribute_error.py

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

    the terminal is my friend, and shows AttributeError

    AttributeError: type object 'AClass'
                    has no attribute 'method_08'.
                    Did you mean: 'method_00'?
    
  • I add a method definition for method_08 to the definition of AClass in attribute_error.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.AClass().method_09 from test_attribute_error.py

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

    the terminal is my friend, and shows AttributeError

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

    25class AClass(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
    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 AClass in attribute_error.py in the src folder, and I can use it from outside the file with src.attribute_error.AClass().method_09()

    src.attribute_error.AClass().method_09
    src
    └── attribute_error.py
        └── class AClass(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_class_methods'
    

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


close the project

  • I close attribute_error.py and 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 attribute_error.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?

You know

Would you like to see another way to write tests?


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.