AttributeError with assertRaises


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

    38        src.attribute_error.AClass().attribute_06
    39        src.attribute_error.AClass().attribute_07
    40        src.attribute_error.AClass().attribute_08
    41        src.attribute_error.AClass().attribute_09
    42
    43    def test_attribute_error_w_class_methods(self):
    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 None, in attribute_error.py

    25class AClass(object):
    26
    27    attribute_00 = None
    28    attribute_01 = None
    29    attribute_02 = None
    30    attribute_03 = None
    31    attribute_04 = None
    32    attribute_05 = None
    33    attribute_06 = None
    34    attribute_07 = None
    35    attribute_08 = None
    36    attribute_09 = None
    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

    25class AClass(object):
    26
    27    attribute_00 = None
    28    attribute_01 = None
    29    attribute_02 = None
    30    attribute_03 = None
    31    attribute_04 = None
    32    attribute_05 = None
    33    attribute_06 = None
    34    attribute_07 = None
    35    attribute_08 = None
    36    attribute_09 = None
    37
    38    # method_00 = None
    39    def method_00():
    40        return None
    
    • the test passes because method_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 call method_00 from outside the file with src.attribute_error.AClass.method_00() or src.attribute_error.AClass().method_00()


REFACTOR: make it better


  • I remove the commented line

    25class AClass(object):
    26
    27    attribute_00 = None
    28    attribute_01 = None
    29    attribute_02 = None
    30    attribute_03 = None
    31    attribute_04 = None
    32    attribute_05 = None
    33    attribute_06 = None
    34    attribute_07 = None
    35    attribute_08 = None
    36    attribute_09 = None
    37
    38    def method_00():
    39        return None
    
  • You know the “drill”, I add a line for src.attribute_error.AClass.method_01 to test_attribute_error.py

    43    def test_attribute_error_w_class_methods(self):
    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

    25class AClass(object):
    26
    27    attribute_00 = None
    28    attribute_01 = None
    29    attribute_02 = None
    30    attribute_03 = None
    31    attribute_04 = None
    32    attribute_05 = None
    33    attribute_06 = None
    34    attribute_07 = None
    35    attribute_08 = None
    36    attribute_09 = None
    37
    38    def method_00():
    39        return None
    40
    41    def method_01():
    42        return None
    

    the test passes because in this case it does not matter if I reference the method (AClass.method_01) or call it (AClass.method_01()).

  • I add a line for src.attribute_error.AClass.method_02 to test_attribute_error.py

    43    def test_attribute_error_w_class_methods(self):
    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

    69    def method_01():
    70        return None
    71
    72    def method_02():
    73        return None
    

    the terminal is my friend, and shows TypeError

    TypeError: AClass.method_02() takes
               0 positional arguments but 1 was given
    

    because this happens when AClass().method_02() is called

    AClass().method_02()
        AClass.method_02(AClass)
    

    which raises TypeError since the definition of method_02 does not allow it take any positional arguments (the parentheses are empty).

  • I add self to the parentheses of method_02

    72    # def method_02():
    73    def method_02(self):
    74        return None
    

    the test passes because this happens when AClass().method_02() is called

    AClass().method_02()
        AClass.method_02(self)
    

    where self is AClass.

  • I add the staticmethod decorator method definition instead of self since it does not use anything in the class. That way I do not send more information than what the method needs.

    69    def method_01():
    70        return None
    71
    72    @staticmethod
    73    def method_02():
    74    # def method_02(self):
    75        return None
    

    the test is still green because this now happens when AClass().method_02() is called

    AClass().method_02()
        AClass.method_02()
    

    with the staticmethod decorator it does not matter if I call the method from an instance (AClass()) or from the class (AClass).

  • I remove the commented line

    69    def method_01():
    70        return None
    71
    72    @staticmethod
    73    def method_02():
    74        return None
    
  • I add a line for src.attribute_error.AClass.method_03 to test_attribute_error.py

    43    def test_attribute_error_w_class_methods(self):
    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 the method to the definition of AClass in attribute_error.py

    72    @staticmethod
    73    def method_02():
    74        return None
    75
    76    def method_03():
    77        return None
    

    the test passes because in this case I reference the method (AClass().method_03), I do not call it (AClass().method_03()).

  • I add a line for src.attribute_error.AClass.method_04 to test_attribute_error.py

    43    def test_attribute_error_w_class_methods(self):
    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 the method to the definition of AClass in attribute_error.py

    76    def method_03():
    77        return None
    78
    79    def method_04():
    80        return None
    

    the terminal is my friend, and shows TypeError

    TypeError: AClass.method_04() takes
               0 positional arguments but 1 was given
    

    because this happens when AClass().method_04() is called

    AClass().method_04()
        AClass.method_04(AClass)
    

    which raises TypeError since the definition of method_04 does not allow it take any positional arguments.

  • I add the staticmethod decorator to the definition for method_04

    76    def method_03():
    77        return None
    78
    79    @staticmethod
    80    def method_04():
    81        return None
    

    the test passes because this now happens when AClass().method_04() is called

    AClass().method_04()
        AClass.method_04()
    

    with the staticmethod decorator it does not matter if I call the method from an instance (AClass()) or from the class (AClass).

  • I add a line for src.attribute_error.AClass.method_05 to test_attribute_error.py

    43    def test_attribute_error_w_class_methods(self):
    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 the method to the definition of AClass in attribute_error.py

    79    @staticmethod
    80    def method_04():
    81        return None
    82
    83    def method_05():
    84        return None
    

    the test passes.

  • I add a line for src.attribute_error.AClass.method_06 to test_attribute_error.py

    43    def test_attribute_error_w_class_methods(self):
    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 the method to the definition of AClass in attribute_error.py

    83    def method_05():
    84        return None
    85
    86    def method_06():
    87        return None
    

    the test passes because this happens when AClass.method_06() is called

    AClass.method_06()
    

    I called the method with the class (AClass.method_06()) not an instance of the class (AClass().method_06()).

  • I add a line for src.attribute_error.AClass.method_07 to test_attribute_error.py

    43    def test_attribute_error_w_class_methods(self):
    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 the method to the definition of AClass in attribute_error.py

    86    def method_06():
    87        return None
    88
    89    def method_07():
    90        return None
    

    the test passes.

  • I add a line for src.attribute_error.AClass.method_08 to test_attribute_error.py

    43    def test_attribute_error_w_class_methods(self):
    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 the method to the definition of AClass in attribute_error.py

    89    def method_07():
    90        return None
    91
    92    def method_08():
    93        return None
    

    the terminal is my friend, and shows TypeError

    TypeError: AClass.method_08() takes
               0 positional arguments but 1 was given
    

    because this happens when AClass().method_08() is called

    AClass().method_08()
        AClass.method_08(AClass)
    

    which raises TypeError since the definition of method_08 does not allow it take any positional arguments (the parentheses are empty).

  • I add the staticmethod decorator to the method definition since it does not use anything in the class

    89    def method_07():
    90        return None
    91
    92    @staticmethod
    93    def method_08():
    94        return None
    

    the test passes because this now happens when AClass().method_08() is called

    AClass().method_08()
        AClass.method_08()
    

    with the staticmethod decorator it does not matter if I call the method from an instance (AClass()) or from the class (AClass).

  • I add a line for src.attribute_error.AClass.method_09 to test_attribute_error.py

    43    def test_attribute_error_w_class_methods(self):
    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# AttributeError
    59# NameError
    60# TypeError
    61# 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 the method to the definition of AClass in attribute_error.py

    25class AClass(object):
    26
    27    attribute_00 = None
    28    attribute_01 = None
    29    attribute_02 = None
    30    attribute_03 = None
    31    attribute_04 = None
    32    attribute_05 = None
    33    attribute_06 = None
    34    attribute_07 = None
    35    attribute_08 = None
    36    attribute_09 = None
    37
    38    def method_00():
    39        return None
    40
    41    def method_01():
    42        return None
    43
    44    @staticmethod
    45    def method_02():
    46        return None
    47
    48    def method_03():
    49        return None
    50
    51    @staticmethod
    52    def method_04():
    53        return None
    54
    55    def method_05():
    56        return None
    57
    58    def method_06():
    59        return None
    60
    61    def method_07():
    62        return None
    63
    64    @staticmethod
    65    def method_08():
    66        return None
    67
    68    def method_09():
    69        return None
    

    the test passes because in this case I reference the method (AClass().method_09), I do not call it (AClass().method_09()).

  • 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 because in Python everything is an object

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 know where the extra attributes and methods of the Person class came from?


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.