def my_func(in):
if type(in) != type(""): raise ValueError()
. . . which emulate static types, but is still not a compile-time error. In my early Python libraries, I found I was doing something of this sort because I wanted it to be robust, even at the cost of performance (this is a case where C++ wins: C++ is plenty fast, you don't have to do this particular kind of error checking, and you can put #ifdef/#endif around error-checking sections so that the code isn't even there when you don't want it).