, as in life, it’s important to know what you’re working with. Python’s dynamic type system appears to make this difficult at first glance. A type is a promise about the values an object can hold and the operations that apply to it: an integer can be multiplied or compared, a string concatenated, a dictionary indexed by key. Many languages check these promises before the program runs. Rust and Go catch type mismatches at compile time and refuse to produce a runnable binary if they fail; TypeScript runs its checks during a separate compile step. Python does no checking at all by default, and the consequences play out at runtime. In Python, a name binds only to a value. The name itself carries no commitment about the value’s type, and the next assignment can replace the value with one of a completely different kind. A function will accept whatever you pass it and return whatever its body produces; if the type of either is not what you intended, the interpreter will not say so.…