One way would be to explicitly check if the argument is a list or a string and handle it differently within conditional clauses.
An alternative that I think might be nicer (if it's suitable for your use case) might be the following:
def runthis(*stringinput):
for t in stringinput:
t = t.upper()
print(t)
print()
runthis("test") # TEST
runthis("another", "test") # ANOTHER TEST
runthis(*["one", "final", "test"]) # ONE FINAL TEST
However, this approach isn't appropriate if calling code may provide lists without splatting it.
This approach relies on the usage of the * operator, which here is used in two different ways.
In the function definition context (*stringinput), this operator essentially makes stringinput a variadic argument; that is, an argument that "scoops up" all arguments passed to the function into a tuple, which for the purposes of runthis acts like a list (it can be iterated over). If I were to make a call runthis("foo", "bar", "baz"), stringinput would have the value ("foo", "bar", "baz").
You can read more about variadic arguments here.
In the function invocation context (runthis(*["one", "final", "test"])), this operator will "splat" or unpack each element of the list. Essentially, runthis(*["one", "final", "test"]) is equivalent to runthis("one", "final", "test").
You can read more about splatting here.