TypeError
preview
Here are the tests I have by the end of the chapter
1import src.type_error
2import unittest
3
4
5class TestTypeError(unittest.TestCase):
6
7 def test_type_error_w_the_uncallables(self):
8 src.type_error.none()
9 src.type_error.false()
10 src.type_error.true()
11 src.type_error.an_integer()
12 src.type_error.a_float()
13 src.type_error.a_string()
14 src.type_error.a_tuple()
15 src.type_error.a_list()
16 src.type_error.a_set()
17 src.type_error.a_dictionary()
18
19 def test_type_error_w_function_signatures(self):
20 src.type_error.function_00('a')
21 src.type_error.function_01('a', 'b')
22 src.type_error.function_02('a', 'b', 'c')
23 src.type_error.function_03('a', 'b', 'c', 'd')
24
25 def test_type_error_w_objects_that_do_not_mix(self):
26 with self.assertRaises(TypeError):
27 None + False
28 with self.assertRaises(TypeError):
29 True - 'text'
30 with self.assertRaises(TypeError):
31 (0, 1, 2, 'n') * [0, 1, 2, 'n']
32 with self.assertRaises(TypeError):
33 {0, 1, 2, 'n'} / {'key': 'value'}
34
35
36# Exceptions seen
37# AssertionError
38# AttributeError
39# TypeError
questions about TypeError
Here are questions you can answer after going through this chapter
start the project
I open a terminal
I type pwd to make sure I am in the
pumping_pythonfolderpwdthe terminal goes back to the command line
.../pumping_pythonNote
if you are not in the
pumping_pythonfolder, trycd ~/pumping_pythonI name this project
type_errorI open
makePythonTdd.shormakePythonTdd.ps1in the editorTip
Here is a quick way to open
makePythonTdd.shormakePythonTdd.ps1if you are using Visual Studio Codecode makePythonTdd.shon Windows without Windows Subsystem for Linux use
code makePythonTdd.ps1I change everywhere I have
exceptionsto the name of this project1#!/bin/bash 2mkdir type_error 3cd type_error 4mkdir src 5touch src/type_error.py 6mkdir tests 7touch tests/__init__.py 8 9echo "import unittest 10 11 12class TestTypeError(unittest.TestCase): 13 14 def test_failure(self): 15 self.assertFalse(True) 16 17 18# Exceptions seen 19# AssertionError 20" > tests/test_type_error.pyAttention
on Windows without Windows Subsystem for Linux use
makePythonTdd.ps1NOTmakePythonTdd.sh1mkdir type_error 2cd type_error 3mkdir src 4New-Item src/type_error.py 5mkdir tests 6New-Item tests/__init__.py 7 8"import unittest 9 10 11class TestTypeError(unittest.TestCase): 12 13 def test_failure(self): 14 self.assertFalse(True) 15 16# Exceptions seen 17# AssertionError 18" | Out-File tests/test_type_error.pyI run the program in the terminal
./makePythonTdd.shAttention
on Windows without Windows Subsystem for Linux use
makePythonTdd.ps1NOTmakePythonTdd.sh./makePythonTdd.ps1the terminal shows AssertionError
======================================= FAILURES ======================================= ______________________________ TestTypeError.test_failure ______________________________ self = <tests.test_exceptions.TestTypeError testMethod=test_failure> def test_failure(self): > self.assertFalse(True) E AssertionError: True is not false tests/test_type_error.py:7: AssertionError =============================== short test summary info ================================ FAILED tests/test_type_error.py::TestTypeError::test_failure - AssertionError: True is not false ================================== 1 failed in X.YZs ===================================I hold ctrl (Windows/Linux) or option or command (MacOS) on the keyboard and use the mouse to click on
tests/test_type_error.py:7to open it in the editor-
7 self.assertFalse(False)the test passes
test_type_error_w_the_uncallables
There are objects that can NOT be called
RED: make it fail
I add an import statement at the top of
test_type_error.py1import src.type_error 2import unittestI change
test_failuretotest_type_error_w_the_uncallableswith a failing line5class TestTypeError(unittest.TestCase): 6 7 def test_type_error_w_the_uncallables(self): 8 src.type_error.none()the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'none'there is nothing in
type_error.pyin thesrcfolder yetI add AttributeError to the list of Exceptions seen
11# Exceptions seen 12# AssertionError 13# AttributeError
GREEN: make it pass
I open
type_error.pyfrom thesrcfolder in the editor of my Integrated Development Environment (IDE), then add the name and point it to None1none = NoneTypeError: 'NoneType' object is not callablethe
()to the right ofsrc.type_error.nonemakes it a call
I add TypeError to the list of Exceptions seen in
test_type_error.py11# Exceptions seen 12# AssertionError 13# AttributeError 14# TypeErrorI make
nonea function intype_error.pyto make it callable1def none(): 2 return Nonethe test passes
REFACTOR: make it better
I add another failing line to
test_type_error.py7 def test_type_error_w_the_uncallables(self): 8 src.type_error.none() 9 src.type_error.false()the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'false'nothing is named
falseintype_error.pyI add the name to
type_error.pyand point it to False1def none(): 2 return None 3 4 5false = FalseTypeError: 'bool' object is not callableI change the variable to a function
1def none(): 2 return None 3 4def false(): 5 return Falsethe terminal shows green again
I add a line to test the other boolean in
test_type_error.py7 def test_type_error_w_the_uncallables(self): 8 src.type_error.none() 9 src.type_error.false() 10 src.type_error.true()the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'true'there is nothing named
trueintype_error.pyI add the name and point it to True in
type_error.py5def false(): 6 return False 7 8 9true = TrueTypeError: 'bool' object is not callableI make it a function
5def false(): 6 return False 7 8 9def true(): 10 return Truethe test passes. I can call a function, I cannot call a boolean or None
I add a failing line to
test_type_error.py8 src.type_error.none() 9 src.type_error.false() 10 src.type_error.true() 11 src.type_error.an_integer()the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'an_integer'I add the name and point it to an integer in
type_error.py9def true(): 10 return True 11 12 13an_integer = 1234I change the variable to a funcion
9def true(): 10 return True 11 12 13def an_integer(): 14 return 1234the test passes. I can call a function, I cannot call an integer, a boolean or None
I add a line for a float in
test_type_error.py9 src.type_error.false() 10 src.type_error.true() 11 src.type_error.an_integer() 12 src.type_error.a_float()the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'a_float'I add the name and point it to a float in
type_error.py13def an_integer(): 14 return 1234 15 16 17a_float = 1.234TypeError: 'float' object is not callableI make
a_floata function13def an_integer(): 14 return 1234 15 16 17def a_float(): 18 return 1.234the test passes. I can call a function, I cannot call a float, integer, boolean or None
I add a line for a string (anything in quotes) in
test_type_error.py10 src.type_error.true() 11 src.type_error.an_integer() 12 src.type_error.a_float() 13 src.type_error.a_string()the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'a_string'I add the name and point it to a string in
type_error.py17def a_float(): 18 return 1.234 19 20 21a_string = 'a string'TypeError: 'str' object is not callableI change
a_stringto a function17def a_float(): 18 return 1.234 19 20 21def a_string(): 22 return 'a string'the test passes. I can call a function. I cannot call a string, a float, integer, boolean or None
I add a failing line for a tuple (anything in parentheses
(), separated by a comma) intest_type_error.py11 src.type_error.an_integer() 12 src.type_error.a_float() 13 src.type_error.a_string() 14 src.type_error.a_tuple()the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'a_tuple'I add the name and point it to a tuple in
type_error.py21def a_string(): 22 return 'a string' 23 24 25a_tuple = (1, 2, 3, 'n')TypeError: 'tuple' object is not callableI change it to a function
21def a_string(): 22 return 'a string' 23 24 25def a_tuple(): 26 return (1, 2, 3, 'n')the test passes. I can call a function. I cannot call a tuple, string, float, integer boolean or None
I add another line to
test_type_error.py12 src.type_error.a_float() 13 src.type_error.a_string() 14 src.type_error.a_tuple() 15 src.type_error.a_list()the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'a_list'I add the name and point it to a list (anything in square brackets (
[]) intype_error.py25def a_tuple(): 26 return (1, 2, 3, 'n') 27 28 29a_list = [1, 2, 3, 'n']TypeError: 'list' object is not callableI change
a_listto a function25def a_tuple(): 26 return (1, 2, 3, 'n') 27 28 29def a_list(): 30 return [1, 2, 3, 'n']the test passes. I can call a function, I cannot call a list, tuple, string, float, integer, boolean or None
I add another failing line to
test_type_error.py13 src.type_error.a_string() 14 src.type_error.a_tuple() 15 src.type_error.a_list() 16 src.type_error.a_set()the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'a_set'I add the name and point it to a set in
type_error.py29def a_list(): 30 return [1, 2, 3, 'n'] 31 32 33a_set = {1, 2, 3, 'n'}TypeError: 'set' object is not callableI make it a function
29def a_list(): 30 return [1, 2, 3, 'n'] 31 32 33def a_set(): 34 return {1, 2, 3, 'n'}the test passes. I can call a function, I cannot call a set, list, tuple, string, float, integer, boolean or None
I add the last failing line for this test to
test_type_error.py7 def test_type_error_w_the_uncallables(self): 8 src.type_error.none() 9 src.type_error.false() 10 src.type_error.true() 11 src.type_error.an_integer() 12 src.type_error.a_float() 13 src.type_error.a_string() 14 src.type_error.a_tuple() 15 src.type_error.a_list() 16 src.type_error.a_set() 17 src.type_error.a_dictionary() 18 19 20# Exceptions seenthe terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'a_dictionary'I add the name and point it to a dictionary in
type_error.py33def a_set(): 34 return {1, 2, 3, 'n'} 35 36 37a_dictionary = {'key': 'value'}TypeError: 'dict' object is not callableI change it to a function
33def a_set(): 34 return {1, 2, 3, 'n'} 35 36 37def a_dictionary(): 38 return {'key': 'value'}the terminal shows green again. I can call a function, I cannot call a dictionary, set, list, tuple, string, float, integer, boolean or None
It is safe to say that I cannot call data structures because they are NOT callable. I can call functions, they are callable
test_type_error_w_function_signatures
When I call a function I have to match its definition also known as its signature or I get TypeError
RED: make it fail
I add a new test to
test_type_error.py17 src.type_error.a_dictionary() 18 19 def test_type_error_w_function_signatures(self): 20 src.type_error.function_00('a') 21 22 23# Exceptions seenthe terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'function_00'
GREEN: make it pass
I add the function to
type_error.py37def a_dictionary(): 38 return {'key': 'value'} 39 40 41def function_00(): 42 return NoneTypeError: function_00() takes 0 positional arguments but 1 was givenbecause
function_00is called with'a'as input and the definition does not allow any inputsI add a name in parentheses to the function definition
41def function_00(the_input): 42 return Nonethe test passes
I have to call a function in a way that matches its definition or I get TypeError
REFACTOR: make it better
I add a new failing line to
test_type_error.py19def test_type_error_w_function_signatures(self): 20 src.type_error.function_00('a') 21 src.type_error.function_01('a', 'b')the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'function_01'. Did you mean: 'function_00'?I add the function to
type_error.py41def function_00(the_input): 42 return None 43 44 45def function_01(the_input): 46 return NoneTypeError: function_01() takes 1 positional argument but 2 were giventhe definition only allows one input, and the test sent two
I change the first name, then add another name in parentheses so that the call to the function and its definition match
45def function_01(first, second): 46 return Nonethe test passes
I add another failing line to
test_type_error.py19 def test_type_error_w_function_signatures(self): 20 src.type_error.function_00('a') 21 src.type_error.function_01('a', 'b') 22 src.type_error.function_02('a', 'b', 'c')the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'function_02'. Did you mean: 'function_00'?I add the function to
type_error.py45def function_01(first, second): 46 return None 47 48 49def function_02(first, second): 50 return NoneTypeError: function_02() takes 2 positional arguments but 3 were givenI change the name of the first input, then add another name in parentheses to make the number of inputs match
49def function_02(first, second, third): 50 return Nonethe test passes
I add one more failing line to
test_type_error.py19 def test_type_error_w_function_signatures(self): 20 src.type_error.function_00('a') 21 src.type_error.function_01('a', 'b') 22 src.type_error.function_02('a', 'b', 'c') 23 src.type_error.function_03('a', 'b', 'c', 'd')the terminal shows AttributeError
AttributeError: module 'src.type_error' has no attribute 'function_03'. Did you mean: 'function_00'?I add the function to
type_error.py49def function_02(first, second, third): 50 return None 51 52 53def function_03(first, second, third): 54 return NoneTypeError: function_03() takes 3 positional arguments but 4 were givenI add a 4th name in parentheses to the definition
53def function_03(first, second, third, fourth): 54 return Nonethe test passes
I have to call a function with the same number of inputs its definition expects
test_type_error_w_objects_that_do_not_mix
Some operations do not work if the objects are NOT the same type
RED: make it fail
I add a new test with a failing line in test_type_error.py
23 src.type_error.function_03('a', 'b', 'c', 'd')
24
25 def test_type_error_w_objects_that_do_not_mix(self):
26 None + False
27
28
29# Exceptions seen
TypeError: unsupported operand type(s) for +: 'NoneType' and 'bool'
I cannot do arithmetic with None
GREEN: make it pass
I add the assertRaises method
25 def test_type_error_w_objects_that_do_not_mix(self):
26 with self.assertRaises(TypeError):
27 None + False
the test passes
REFACTOR: make it better
I add another failing line to the test
25 def test_type_error_w_objects_that_do_not_mix(self): 26 with self.assertRaises(TypeError): 27 None + False 28 True - 'text'TypeError: unsupported operand type(s) for -: 'bool' and 'str'I use assertRaises to handle the Exception
25 def test_type_error_w_objects_that_do_not_mix(self): 26 with self.assertRaises(TypeError): 27 None + False 28 with self.assertRaises(TypeError): 29 True - 'text'the test passes
I add another failing line
25 def test_type_error_w_objects_that_do_not_mix(self): 26 with self.assertRaises(TypeError): 27 None + False 28 with self.assertRaises(TypeError): 29 True - 'text' 30 (0, 1, 2, 'n') * [0, 1, 2, 'n']TypeError: can't multiply sequence by non-int of type 'list'I add assertRaises
25 def test_type_error_w_objects_that_do_not_mix(self): 26 with self.assertRaises(TypeError): 27 None + False 28 with self.assertRaises(TypeError): 29 True - 'text' 30 with self.assertRaises(TypeError): 31 (0, 1, 2, 'n') * [0, 1, 2, 'n'] 32 33# Exceptions seenthe test passes
I add another failing line
25 def test_type_error_w_objects_that_do_not_mix(self): 26 with self.assertRaises(TypeError): 27 None + False 28 with self.assertRaises(TypeError): 29 True - 'text' 30 with self.assertRaises(TypeError): 31 (0, 1, 2, 'n') * [0, 1, 2, 'n'] 32 {0, 1, 2, 'n'} / {'key': 'value'}TypeError: unsupported operand type(s) for /: 'set' and 'dict'I add assertRaises
25def test_type_error_w_objects_that_do_not_mix(self): 26 with self.assertRaises(TypeError): 27 None + False 28 with self.assertRaises(TypeError): 29 True - 'text' 30 with self.assertRaises(TypeError): 31 (0, 1, 2, 'n') * [0, 1, 2, 'n'] 32 with self.assertRaises(TypeError): 33 {0, 1, 2, 'n'} / {'key': 'value'}the terminal shows all tests are passing
close the project
I close
test_type_error.pyandtype_error.pyin the editorthen I click in the terminal and exit the tests with ctrl+c on the keyboard, the terminal shows
.../pumping_pythonI am back in the
pumping_pythondirectory
Note
on Windows without Windows Subsystem for Linux
the terminal shows
(.venv) ...\pumping_python\type_errorI deactivate the virtual environment
deactivatethe terminal goes back to the command line,
(.venv)is no longer on the left side...\pumping_python\type_errorI change directory to the parent of
type_errorcd ..the terminal shows
...\pumping_pythonI am back in the
pumping_pythondirectory
review
The calculator program can take 2 inputs and check if they are both numbers, then add, subtract, multiply or divide them
Even though the program says it only works with numbers, I did not add tests for tuples, lists, sets, and dictionaries, though they are touched in test_type_error_w_objects_that_do_not_mix, Do you want to add them or do we already have enough tests to know what would happen?
I ran tests for TypeError with
How many questions can you answer after going through this chapter?
code from the chapter
what is next?
you know
how to make a Python Test Driven Development environment automatically or how to make a Python Test Driven Development environment automatically on Windows without Windows Subsystem for Linux
Would you like to use what you know so far with the Calculator?
rate pumping python
If this has been a 7 star experience for you, please leave a 5 star review. It helps other people get into the book too