what causes AttributeError?


So far, all the tests show that I get AttributeError when I use a name that is NOT in an object.


what is an attribute?

An attribute is a name (variable?) for something that belongs to an object (a class), for example, a human being has attributes like height, weight, sex and color, they are also known as properties.


preview

I have these tests by the end of the chapter

 1import src.attribute_error
 2import unittest
 3
 4
 5class TestAttributeError(unittest.TestCase):
 6
 7    def test_attribute_error_w_variables(self):
 8        src.attribute_error.variable_00
 9        src.attribute_error.variable_01
10        src.attribute_error.variable_02
11        src.attribute_error.variable_03
12        src.attribute_error.variable_04
13        src.attribute_error.variable_05
14        src.attribute_error.variable_06
15        src.attribute_error.variable_07
16        src.attribute_error.variable_08
17        src.attribute_error.variable_09
18
19    def test_attribute_error_w_functions(self):
20        src.attribute_error.function_00()
21        src.attribute_error.function_01()
22        src.attribute_error.function_02()
23        src.attribute_error.function_03()
24        src.attribute_error.function_04()
25        src.attribute_error.function_05()
26        src.attribute_error.function_06()
27        src.attribute_error.function_07()
28        src.attribute_error.function_08()
29        src.attribute_error.function_09()
30
31    def test_attribute_error_w_class_attributes(self):
32        src.attribute_error.AClass.attribute_00
33        src.attribute_error.AClass.attribute_01
34        src.attribute_error.AClass.attribute_02
35        src.attribute_error.AClass.attribute_03
36        src.attribute_error.AClass.attribute_04
37        src.attribute_error.AClass().attribute_05
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        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

start the project

  • I name this project attribute_error

  • I open a terminal

  • I use uv to make a directory for the project and initialize it

    uv init attribute_error
    

    the terminal shows

    Initialized project `attribute-error`
    at `.../pumping_python/attribute_error`
    

    then goes back to the command line.

  • I change directory to the project

    cd attribute_error
    

    the terminal shows I am in the attribute_error folder

    .../pumping_python/attribute_error
    
  • I make a directory for the source code

    mkdir src
    

    the terminal goes back to the command line.

  • I use the mv program to change the name of main.py to attribute_error.py and move it to the src folder

    mv main.py src/attribute_error.py
    
    Move-Item main.py src/attribute_error.py
    

    the terminal goes back to the command line.

  • I make a directory for the tests

    mkdir tests
    

    the terminal goes back to the command line.

  • I make the tests directory a Python package

    Danger

    use 2 underscores (__) before and after init for __init__.py not _init_.py

    touch tests/__init__.py
    
    New-Item tests/__init__.py
    

    the terminal goes back to the command line.

  • I make a Python file for the tests in the tests directory

    touch tests/test_attribute_error.py
    
    New-Item tests/test_attribute_error.py
    

    the terminal goes back to the command line.

  • I open test_attribute_error.py

  • I add the first failing test to test_attribute_error.py

    1import unittest
    2
    3
    4class TestAttributeError(unittest.TestCase):
    5
    6    def test_failure(self):
    7        self.assertFalse(True)
    
  • I go back to the terminal to make a requirements file for the Python packages I need

    echo "pytest-watcher" > requirements.txt
    

    the terminal goes back to the command line.

  • I add the new files and folder to git for tracking

    git add .
    

    the terminal goes back to the command line.

  • I add a git commit message

    git commit -am 'setup project'
    

    the terminal shows a summary of the changes then goes back to the command line.

  • I use uv to install pytest-watcher with the requirements file

    uv add --requirement requirements.txt
    

    the terminal shows that it installed pytest-watcher and its dependencies.

  • I use pytest-watcher to run the tests automatically

    uv run pytest-watcher . --now
    

    the terminal is my friend, and shows AssertionError

    ======================== FAILURES ========================
    ________________ TestAttributeError.test_failure _________________
    
    self = <tests.test_attribute_error.AttributeError testMethod=test_failure>
    
        def test_failure(self):
    >       self.assertFalse(True)
    E       AssertionError: True is not false
    
    tests/test_attribute_error.py:7: AssertionError
    ================ short test summary info =================
    FAILED tests/test_attribute_error.py::TestAttributeError::test_failure - AssertionError: True is not false
    =================== 1 failed in X.YZs ====================
    

    because True is NOT False

    if the terminal does not show the same error, then check

    • if your tests/__init__.py has two underscores (__) before and after init for __init__.py not _init_.py

    • if you ran echo "pytest-watcher" > requirements.txt, to add pytest-watcher to the requirements file

    fix those errors and try to run uv run pytest-watcher . --now again

  • I add AssertionError to the list of Exceptions seen in test_attribute_error.py

     4class TestAttributeError(unittest.TestCase):
     5
     6    def test_failure(self):
     7        self.assertFalse(True)
     8
     9
    10# Exceptions seen
    11# AssertionError
    
  • then I change True to False in the assertion

    7        self.assertFalse(False)
    

    the test passes.


test_attribute_error_w_variables


RED: make it fail


  • I add an import statement at the top of test_attribute_error.py

    1import src.attribute_error
    2import unittest
    
  • I change test_failure to test_attribute_error_w_variables

     5class TestAttributeError(unittest.TestCase):
     6
     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9
    10
    11# Exceptions seen
    

    I think of src.attribute_error.variable_00 as an address

    • src is the src folder

    • src.attribute_error points to attribute_error.py in the src folder

    • src.attribute_error.variable_00 points to variable_00 in attribute_error.py in the src folder

    • since there is nothing in attribute_error.py named variable_00, Python cannot find variable_00 inside attribute_error.py and raises AttributeError

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

    variable_00 is NOT an attribute of attribute_error.py in the src folder

  • I add AttributeError to the list of Exceptions seen in test_attribute_error.py

    11# Exceptions seen
    12# AssertionError
    13# AttributeError
    

GREEN: make it pass


  • I open attribute_error.py from the src folder of my Integrated Development Environment (IDE)

  • I delete all the text in the file, then add the name to attribute_error.py

    1variable_00
    

    the terminal is my friend, and shows NameError

    NameError: name 'variable_00' is not defined
    

    because I used a name that is not defined in this file

  • I add NameError to the list of Exceptions seen in test_attribute_error.py

    11# Exceptions seen
    12# AssertionError
    13# AttributeError
    14# NameError
    
  • I point variable_00 to None, in attribute_error.py

    1variable_00 = None
    
    • the test passes because variable_00 is now an attribute/property of attribute_error.py in the src folder

    • I can use it from outside the file with src.attribute_error.variable_00


REFACTOR: make it better


  • I do the same test a few more times as a drill in test_attribute_error.py

     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9        src.attribute_error.variable_01
    10
    11
    12# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'variable_01'.
                    Did you mean: 'variable_00'?
    
  • I add the name to attribute_error.py

    1variable_00 = None
    2variable_01
    

    the terminal is my friend, and shows NameError

    NameError: name 'variable_01' is not defined
    
  • I point it to None to define it

    1variable_00 = None
    2variable_01 = None
    

    the test passes.

  • I add another statement to test_attribute_error.py

     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9        src.attribute_error.variable_01
    10        src.attribute_error.variable_02
    11
    12
    13# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'variable_02'.
                    Did you mean: 'variable_00'?
    
  • I add the name and point it to None in attribute_error.py

    1variable_00 = None
    2variable_01 = None
    3variable_02 = None
    

    the test passes.

  • I add a line for src.attribute_error.variable_03 in test_attribute_error.py

     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9        src.attribute_error.variable_01
    10        src.attribute_error.variable_02
    11        src.attribute_error.variable_03
    12
    13
    14# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'variable_03'.
                    Did you mean: 'variable_00'?
    
  • I add the variable to attribute_error.py

    1variable_00 = None
    2variable_01 = None
    3variable_02 = None
    4variable_03 = None
    

    the test passes.

  • I add a line for src.attribute_error.variable_04 in test_attribute_error.py

     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9        src.attribute_error.variable_01
    10        src.attribute_error.variable_02
    11        src.attribute_error.variable_03
    12        src.attribute_error.variable_04
    13
    14
    15# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'variable_04'.
                    Did you mean: 'variable_00'?
    
  • I add the variable to attribute_error.py

    1variable_00 = None
    2variable_01 = None
    3variable_02 = None
    4variable_03 = None
    5variable_04 = None
    

    the test passes.

  • I add a line for src.attribute_error.variable_05 in test_attribute_error.py

     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9        src.attribute_error.variable_01
    10        src.attribute_error.variable_02
    11        src.attribute_error.variable_03
    12        src.attribute_error.variable_04
    13        src.attribute_error.variable_05
    14
    15
    16# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'variable_05'.
                    Did you mean: 'variable_00'?
    
  • I add the variable to attribute_error.py

    1variable_00 = None
    2variable_01 = None
    3variable_02 = None
    4variable_03 = None
    5variable_04 = None
    6variable_05 = None
    

    the test passes.

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

     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9        src.attribute_error.variable_01
    10        src.attribute_error.variable_02
    11        src.attribute_error.variable_03
    12        src.attribute_error.variable_04
    13        src.attribute_error.variable_05
    14        src.attribute_error.variable_06
    15
    16
    17# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'variable_06'.
                    Did you mean: 'variable_00'?
    
  • I add the variable to attribute_error.py

    1variable_00 = None
    2variable_01 = None
    3variable_02 = None
    4variable_03 = None
    5variable_04 = None
    6variable_05 = None
    7variable_06 = None
    

    the test passes.

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

     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9        src.attribute_error.variable_01
    10        src.attribute_error.variable_02
    11        src.attribute_error.variable_03
    12        src.attribute_error.variable_04
    13        src.attribute_error.variable_05
    14        src.attribute_error.variable_06
    15        src.attribute_error.variable_07
    16
    17
    18# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'variable_07'.
                    Did you mean: 'variable_00'?
    
  • I add the variable to attribute_error.py

    1variable_00 = None
    2variable_01 = None
    3variable_02 = None
    4variable_03 = None
    5variable_04 = None
    6variable_05 = None
    7variable_06 = None
    8variable_07 = None
    

    the test passes.

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

     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9        src.attribute_error.variable_01
    10        src.attribute_error.variable_02
    11        src.attribute_error.variable_03
    12        src.attribute_error.variable_04
    13        src.attribute_error.variable_05
    14        src.attribute_error.variable_06
    15        src.attribute_error.variable_07
    16        src.attribute_error.variable_08
    17
    18
    19# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'variable_08'.
                    Did you mean: 'variable_00'?
    
  • I add the variable to attribute_error.py

    1variable_00 = None
    2variable_01 = None
    3variable_02 = None
    4variable_03 = None
    5variable_04 = None
    6variable_05 = None
    7variable_06 = None
    8variable_07 = None
    9variable_08 = None
    

    the test passes.

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

     7    def test_attribute_error_w_variables(self):
     8        src.attribute_error.variable_00
     9        src.attribute_error.variable_01
    10        src.attribute_error.variable_02
    11        src.attribute_error.variable_03
    12        src.attribute_error.variable_04
    13        src.attribute_error.variable_05
    14        src.attribute_error.variable_06
    15        src.attribute_error.variable_07
    16        src.attribute_error.variable_08
    17        src.attribute_error.variable_09
    18
    19
    20# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'variable_09'.
                    Did you mean: 'variable_00'?
    
  • I add the variable to attribute_error.py

     1variable_00 = None
     2variable_01 = None
     3variable_02 = None
     4variable_03 = None
     5variable_04 = None
     6variable_05 = None
     7variable_06 = None
     8variable_07 = None
     9variable_08 = None
    10variable_09 = None
    

    the test passes.

  • I open a new terminal then change directories to assertion_error

    cd assertion_error
    

    the terminal shows I am in the assertion_error folder

    .../pumping_python/assertion_error
    
  • I add a git commit message

    git commit -am \
    'add test_what_is_an_assertion'
    

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


test_attribute_error_w_functions


RED: make it fail


I add a test for functions to test_attribute_error.py

15        src.attribute_error.variable_07
16        src.attribute_error.variable_08
17        src.attribute_error.variable_09
18
19    def test_attribute_error_w_functions(self):
20        src.attribute_error.function_00()
21
22
23# Exceptions seen

the terminal is my friend, and shows AttributeError

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

GREEN: make it pass


  • I add the name and point it to None in attribute_error.py

     1variable_00 = None
     2variable_01 = None
     3variable_02 = None
     4variable_03 = None
     5variable_04 = None
     6variable_05 = None
     7variable_06 = None
     8variable_07 = None
     9variable_08 = None
    10variable_09 = None
    11
    12
    13function_00 = None
    

    the terminal is my friend, and shows TypeError

    TypeError: 'NoneType' object is not callable
    

    because I cannot call None like a function.

  • I add TypeError to the list of Exceptions seen in test_attribute_error.py

    23# Exceptions seen
    24# AssertionError
    25# AttributeError
    26# NameError
    27# TypeError
    
  • I change the variable to a function in attribute_error.py

    13# function_00 = None
    14def function_00():
    15    return None
    
    • the test passes because function_00 is now an attribute/property of attribute_error.py in the src folder

    • I can call it from outside the file with src.attribute_error.function_00()


REFACTOR: make it better


  • I remove the commented line

     1variable_00 = None
     2variable_01 = None
     3variable_02 = None
     4variable_03 = None
     5variable_04 = None
     6variable_05 = None
     7variable_06 = None
     8variable_07 = None
     9variable_08 = None
    10variable_09 = None
    11
    12
    13def function_00():
    14    return None
    

    time to make it a drill.

  • I add a call to src.attribute_error.function_01 in test_attribute_error_w_functions in test_attribute_error.py

    19    def test_attribute_error_w_functions(self):
    20        src.attribute_error.function_00()
    21        src.attribute_error.function_01()
    22
    23
    24# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'function_01'.
                    Did you mean: 'function_00'?
    
  • I add the function to attribute_error.py

    13def function_00():
    14    return None
    15
    16
    17def function_01():
    18    return None
    

    the test passes.

  • I add a line for src.attribute_error.function_02 to test_attribute_error_w_functions in test_attribute_error.py

    13    def test_attribute_error_w_functions(self):
    14        src.attribute_error.function_00()
    15        src.attribute_error.function_01()
    16        src.attribute_error.function_02()
    17
    18
    19# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'function_02'.
                    Did you mean: 'function_00'?
    
  • I add a function for it in attribute_error.py

    17def function_01():
    18    return None
    19
    20
    21def function_02():
    22    return None
    

    the test passes.

  • I add a line for src.attribute_error.function_03 to test_attribute_error_w_functions in test_attribute_error.py

    19    def test_attribute_error_w_functions(self):
    20        src.attribute_error.function_00()
    21        src.attribute_error.function_01()
    22        src.attribute_error.function_02()
    23        src.attribute_error.function_03()
    24
    25
    26# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'function_03'.
                    Did you mean: 'function_00'?
    
  • I add a function for it in attribute_error.py

    21def function_02():
    22    return None
    23
    24
    25def function_03():
    26    return None
    

    the test passes.

  • I add a line for src.attribute_error.function_04 to test_attribute_error_w_functions in test_attribute_error.py

    19    def test_attribute_error_w_functions(self):
    20        src.attribute_error.function_00()
    21        src.attribute_error.function_01()
    22        src.attribute_error.function_02()
    23        src.attribute_error.function_03()
    24        src.attribute_error.function_04()
    25
    26
    27# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'function_04'.
                    Did you mean: 'function_00'?
    
  • I add a function for it in attribute_error.py

    25def function_03():
    26    return None
    27
    28
    29def function_04():
    30    return None
    

    the test passes.

  • I add a line for src.attribute_error.function_05 to test_attribute_error_w_functions in test_attribute_error.py

    19    def test_attribute_error_w_functions(self):
    20        src.attribute_error.function_00()
    21        src.attribute_error.function_01()
    22        src.attribute_error.function_02()
    23        src.attribute_error.function_03()
    24        src.attribute_error.function_04()
    25        src.attribute_error.function_05()
    26
    27
    28# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'function_05'.
                    Did you mean: 'function_00'?
    
  • I add a function for it in attribute_error.py

    29def function_04():
    30    return None
    31
    32
    33def function_05():
    34    return None
    

    the test passes.

  • I add a line for src.attribute_error.function_06 to test_attribute_error_w_functions in test_attribute_error.py

    19    def test_attribute_error_w_functions(self):
    20        src.attribute_error.function_00()
    21        src.attribute_error.function_01()
    22        src.attribute_error.function_02()
    23        src.attribute_error.function_03()
    24        src.attribute_error.function_04()
    25        src.attribute_error.function_05()
    26        src.attribute_error.function_06()
    27
    28
    29# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'function_06'.
                    Did you mean: 'function_00'?
    
  • I add a function for it in attribute_error.py

    33def function_05():
    34    return None
    35
    36
    37def function_06():
    38    return None
    

    the test passes.

  • I add a line for src.attribute_error.function_07 to test_attribute_error_w_functions in test_attribute_error.py

    19    def test_attribute_error_w_functions(self):
    20        src.attribute_error.function_00()
    21        src.attribute_error.function_01()
    22        src.attribute_error.function_02()
    23        src.attribute_error.function_03()
    24        src.attribute_error.function_04()
    25        src.attribute_error.function_05()
    26        src.attribute_error.function_06()
    27        src.attribute_error.function_07()
    28
    29
    30# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'function_07'.
                    Did you mean: 'function_00'?
    
  • I add a function for it in attribute_error.py

    37def function_06():
    38    return None
    39
    40
    41def function_07():
    42    return None
    

    the test passes.

  • I add a line for src.attribute_error.function_08 to test_attribute_error_w_functions in test_attribute_error.py

    19    def test_attribute_error_w_functions(self):
    20        src.attribute_error.function_00()
    21        src.attribute_error.function_01()
    22        src.attribute_error.function_02()
    23        src.attribute_error.function_03()
    24        src.attribute_error.function_04()
    25        src.attribute_error.function_05()
    26        src.attribute_error.function_06()
    27        src.attribute_error.function_07()
    28        src.attribute_error.function_08()
    29
    30
    31# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'function_08'.
                    Did you mean: 'function_00'?
    
  • I add a function for it in attribute_error.py

    41def function_07():
    42    return None
    43
    44
    45def function_08():
    46    return None
    

    the test passes.

  • I add a line for src.attribute_error.function_09 to test_attribute_error_w_functions in test_attribute_error.py

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

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.attribute_error'
                    has no attribute 'function_09'.
                    Did you mean: 'function_00'?
    
  • I add a function for it in attribute_error.py

    45def function_08():
    46    return None
    47
    48
    49def function_09():
    50    return None
    

    the test passes.

  • I add a git commit message in the other terminal

    git commit -am \
    'add test_attribute_error_w_functions'
    
  • 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_attributes

The tests 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?


RED: make it fail


  • I go back to the terminal that is running the tests

I add a test for class attributes to test_attribute_error.py

26        src.attribute_error.function_06()
27        src.attribute_error.function_07()
28        src.attribute_error.function_08()
29        src.attribute_error.function_09()
30
31    def test_attribute_error_w_class_attributes(self):
32        src.attribute_error.AClass.attribute_00
33
34
35# Exceptions seen

the terminal is my friend, and shows AttributeError

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

GREEN: make it pass


  • I add a function to attribute_error.py

    49def function_09():
    50    return None
    51
    52
    53def AClass():
    54    return None
    

    the terminal is my friend, and shows AttributeError

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

    53def AClass():
    54
    55    attribute_00 = None
    56    return None
    

    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 within the function when it runs.

  • I use the class keyword to change AClass from a function to a class

    53# def AClass():
    54class AClass(object):
    55
    56    attribute_00 = None
    57    return None
    

    the terminal is my friend, and shows SyntaxError

    E    return None
    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

    35# Exceptions seen
    36# AssertionError
    37# AttributeError
    38# NameError
    39# TypeError
    40# SyntaxError
    
  • I comment out the return statement from AClass in attribute_error.py since it is no longer a function

    53# def AClass():
    54class AClass(object):
    55
    56    attribute_00 = None
    57    # return None
    
    • 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


REFACTOR: make it better


  • I remove the commented lines

    49def function_09():
    50    return None
    51
    52
    53class AClass(object):
    54
    55    attribute_00 = None
    
  • I add a line for src.attribute_error.AClass.attribute_01 to test_attribute_error.py

    31    def test_attribute_error_w_class_attributes(self):
    32        src.attribute_error.AClass.attribute_00
    33        src.attribute_error.AClass.attribute_01
    34
    35
    36# 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 the name to the class definition in attribute_error.py

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    

    the test passes.

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

    31    def test_attribute_error_w_class_attributes(self):
    32        src.attribute_error.AClass.attribute_00
    33        src.attribute_error.AClass.attribute_01
    34        src.attribute_error.AClass.attribute_02
    35
    36
    37# 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 the name to the class definition in attribute_error.py

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    

    the test passes.

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

    31    def test_attribute_error_w_class_attributes(self):
    32        src.attribute_error.AClass.attribute_00
    33        src.attribute_error.AClass.attribute_01
    34        src.attribute_error.AClass.attribute_02
    35        src.attribute_error.AClass.attribute_03
    36
    37
    38# 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 the name to the class definition in attribute_error.py

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    

    the test passes.

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

    31    def test_attribute_error_w_class_attributes(self):
    32        src.attribute_error.AClass.attribute_00
    33        src.attribute_error.AClass.attribute_01
    34        src.attribute_error.AClass.attribute_02
    35        src.attribute_error.AClass.attribute_03
    36        src.attribute_error.AClass.attribute_04
    37
    38
    39# 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 the name to the class definition in attribute_error.py

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    

    the test passes.

  • I add a line for src.attribute_error.AClass().attribute_05 to test_attribute_error.py

    31    def test_attribute_error_w_class_attributes(self):
    32        src.attribute_error.AClass.attribute_00
    33        src.attribute_error.AClass.attribute_01
    34        src.attribute_error.AClass.attribute_02
    35        src.attribute_error.AClass.attribute_03
    36        src.attribute_error.AClass.attribute_04
    37        src.attribute_error.AClass().attribute_05
    38
    39
    40# 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 the name to the class definition in attribute_error.py

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    

    the test passes because in this case it does not matter if I use the class (AClass) or an instance of the class (AClass()).

  • I add a line for src.attribute_error.AClass().attribute_06 to test_attribute_error.py

    31    def test_attribute_error_w_class_attributes(self):
    32        src.attribute_error.AClass.attribute_00
    33        src.attribute_error.AClass.attribute_01
    34        src.attribute_error.AClass.attribute_02
    35        src.attribute_error.AClass.attribute_03
    36        src.attribute_error.AClass.attribute_04
    37        src.attribute_error.AClass().attribute_05
    38        src.attribute_error.AClass().attribute_06
    39
    40
    41# 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 the name to the class definition in attribute_error.py

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    61    attribute_06 = None
    

    the test passes.

  • I add a line for src.attribute_error.AClass().attribute_07 to test_attribute_error.py

    31    def test_attribute_error_w_class_attributes(self):
    32        src.attribute_error.AClass.attribute_00
    33        src.attribute_error.AClass.attribute_01
    34        src.attribute_error.AClass.attribute_02
    35        src.attribute_error.AClass.attribute_03
    36        src.attribute_error.AClass.attribute_04
    37        src.attribute_error.AClass().attribute_05
    38        src.attribute_error.AClass().attribute_06
    39        src.attribute_error.AClass().attribute_07
    40
    41
    42# 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 the name to the class definition in attribute_error.py

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    61    attribute_06 = None
    62    attribute_07 = None
    

    the test passes.

  • I add a line for src.attribute_error.AClass().attribute_08 to test_attribute_error.py

    31    def test_attribute_error_w_class_attributes(self):
    32        src.attribute_error.AClass.attribute_00
    33        src.attribute_error.AClass.attribute_01
    34        src.attribute_error.AClass.attribute_02
    35        src.attribute_error.AClass.attribute_03
    36        src.attribute_error.AClass.attribute_04
    37        src.attribute_error.AClass().attribute_05
    38        src.attribute_error.AClass().attribute_06
    39        src.attribute_error.AClass().attribute_07
    40        src.attribute_error.AClass().attribute_08
    41
    42
    43# 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 the name to the class definition in attribute_error.py

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    61    attribute_06 = None
    62    attribute_07 = None
    63    attribute_08 = None
    

    the test passes.

  • I add a line for src.attribute_error.AClass().attribute_09 to test_attribute_error.py

    31    def test_attribute_error_w_class_attributes(self):
    32        src.attribute_error.AClass.attribute_00
    33        src.attribute_error.AClass.attribute_01
    34        src.attribute_error.AClass.attribute_02
    35        src.attribute_error.AClass.attribute_03
    36        src.attribute_error.AClass.attribute_04
    37        src.attribute_error.AClass().attribute_05
    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
    44# 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 the name to the class definition in attribute_error.py

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    61    attribute_06 = None
    62    attribute_07 = None
    63    attribute_08 = None
    64    attribute_09 = None
    

    the test passes.

  • 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 that is running the tests

  • 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

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    61    attribute_06 = None
    62    attribute_07 = None
    63    attribute_08 = None
    64    attribute_09 = None
    65
    66    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

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    61    attribute_06 = None
    62    attribute_07 = None
    63    attribute_08 = None
    64    attribute_09 = None
    65
    66    # method_00 = None
    67    def method_00():
    68        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

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    61    attribute_06 = None
    62    attribute_07 = None
    63    attribute_08 = None
    64    attribute_09 = None
    65
    66    def method_00():
    67        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

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    61    attribute_06 = None
    62    attribute_07 = None
    63    attribute_08 = None
    64    attribute_09 = None
    65
    66    def method_00():
    67        return None
    68
    69    def method_01():
    70        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

    53class AClass(object):
    54
    55    attribute_00 = None
    56    attribute_01 = None
    57    attribute_02 = None
    58    attribute_03 = None
    59    attribute_04 = None
    60    attribute_05 = None
    61    attribute_06 = None
    62    attribute_07 = None
    63    attribute_08 = None
    64    attribute_09 = None
    65
    66    def method_00():
    67        return None
    68
    69    def method_01():
    70        return None
    71
    72    @staticmethod
    73    def method_02():
    74        return None
    75
    76    def method_03():
    77        return None
    78
    79    @staticmethod
    80    def method_04():
    81        return None
    82
    83    def method_05():
    84        return None
    85
    86    def method_06():
    87        return None
    88
    89    def method_07():
    90        return None
    91
    92    @staticmethod
    93    def method_08():
    94        return None
    95
    96    def method_09():
    97        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

  • 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

because in Python everything is an object.


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

I ran tests for AttributeError with

I also saw these Exceptions


code from the chapter

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


what is next?

I know

Would you like to test None (the simplest object)?


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.