TypeError is Python’s built-in exception for an operation or function given an inappropriate type. It is useful when enforcing an input requirement: a function expecting an iterable can raise TypeError if its argument is not iterable, while a dictionary subclass can raise it when a key or value is not a string. section 14.4.2 section 17.11.2
Python associates types with objects, not variables. A variable can refer to a string and later to an integer, so assigning a value of an unintended type is not itself rejected. Type hints and testing can help find mismatches; a runtime check can raise TypeError when a particular operation requires a particular type. section 1.3.2 section 17.11.2
Reject a non-string dictionary entry
In a dict subclass, `__setitem__` can check `isinstance(key, str)` and `isinstance(value, str)`, raising `TypeError('key is not a string')` or `TypeError('value is not a string')` before calling `super().__setitem__(key, value)`. Check `__init__` too: entries supplied when the instance is created must satisfy the same rule. section 17.11.2
Choose the exception for the failed requirement, rather than adding checks indiscriminately. An input that is not iterable calls for TypeError; an invalid positive-integer argument is treated separately with ValueError. Catching TypeError also requires care: in a word-counting loop, merely catching an unhashable key and then using that key again does not skip it. section 14.4.2
""" Create a dictionary that allows only strings for keys and values"""
class StringDict(dict):
def __setitem__(self, key, value):
if not isinstance(key, str):
raise TypeError('key is not a string') #1
if not isinstance(value, str):
raise TypeError('value is not a string')
super().__setitem__(key, value)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
key_error = any(not isinstance(_, str)
for _ in self.keys()) #2
if key_error:
raise TypeError('key is not a string')
value_error = any(not isinstance(_, str)
for _ in self.values()) #2
if value_error:
raise TypeError('value is not a string')
The complete subclass shows separate checks for item assignment and entries supplied during initialization. section 17.11.2

