According to Wikipedia
Computer scientists consider a language “type-safe” if it does not allow operations or conversions that violate the rules of the type system.
Since Python runtime checks ensure that type system rules are satisfied, we should consider Python a type safe language.
The same point is made by Jason Orendorff and Jim Blandy in Programming Rust:
Note that being type safe is independent of whether a language checks types at compile time or at run time: C checks at compile time, and is not type safe; Python checks at runtime, and is type safe.
Both separate notion of static type checking and type safety.
Is that correct?
Many programmers will equate static type checking to type-safety:
- “language A has static type checking and so it is type-safe”
- “language B has dynamic type checking and so it is not type-safe”
Sadly, it’s not that simple.
In the Real World
For example, C and C++ are not type-safe because you can undermine the type-system via Type punning.
Also, the C/C++ language specifications extensively allow undefined behaviour (UB) rather than explicitly handling errors and this has become the source of security exploits such as the stack smashing exploit and the format string attack. Such exploits shouldn’t be possible in type-safe languages. Early versions of Java had a type bug with its Generics that proved it is was not completely type-safe.
Still today, for programming languages like Python, Java, C++, … it’s hard to show that these languages are completely type-safe because it requires a mathematical proof. These languages are massive and compilers/interpreters have bugs that are continually being reported and getting fixed.
[ Wikipedia ] Many languages, on the other hand, are too big for human-generated type safety proofs, as they often require checking thousands of cases. …. certain errors may occur at run-time due to bugs in the implementation, or in linked libraries written in other languages; such errors could render a given implementation type unsafe in certain circumstances.
Type safety and type systems, while applicable to real-world programming have their roots and definitions coming from academia – and so a formal definition of what exactly is “type safety” comes with difficulty – especially when talking about real programming languages used in the real world. Academics like to mathematically (formally) define tiny programming languages called toy languages. Only for these languages is it possible to show formally that they are type-safe (and prove they the operations are logically correct).
It’s practically assumed proper languages like python, java, c++ are not completely type-safe because they are so large. It’s so easy for a tiny bug to slip through the cracks that would undermine the type system.
- No python is probably not completely type-safe – nobody has proved it, it’s too hard to prove. You’re more likely to find a tiny bug in the language that would demonstrate that it is not type-safe.
- In fact, most programming languages are probably not completely type-safe – all for the same reasons (only toy academic ones have been proven to be)
- You really shouldn’t believe static-typed languages are necessarily type safe. They are usually safer than dynamically-typed languages, but to say that they are completely type-safe with certainty is wrong
as there’s no proof for this.