In complement to the other answers (which are correct), I would add a comment on the typology of cases where one would need such a test.
Distinguishing between a string and a scalar type
If the question is distinguishing between a string and a number, then asking for forgiveness instead of permission works just as well:
a = 1
try:
b = a.upper()
except AttributeError:
...
Since that's the mindset of Python, it often makes things simpler, and it also takes care of the case where a is None. If one is trying to prevent such an error, then it might be easier to let it instead happen and then catch it. It could also be more reliable, because it could also take care of cases one had not thought of.
Distinguishing between a string and other iterables
One case where it won't work, however, is when one wants to distinguish between a string and a list (several libraries do that with function arguments). The problem is that both a string and a list are iterables, so the string might happily run through the code for the list without any error... except that now you have your string cut into pieces of one character.
>>> for el in a: print(el.upper())
...
H
E
L
L
O
(And if the code fails, the error could be confusing.) To avoid that effect:
a = "hello"
if isinstance(a, str):
...
else:
...
In my experience, it's the only case where it's really advisable to use a test with isinstance(x, (str,...)). I am curious to know whether someone knows others?