TL;DR Python doesn't need generics because it is a dynamically typed langauge. This allows us to use so-called duck typing instead of explicit generics.
The first thing to note is that type annotations in python are only suggestions. They help static analysis tools such as code completion while you are writing code but are not enforced at run-time.
With that in mind, let's look at a non-annotated version of your function:
def read(table, fields="*"):
pass
Here, python doesn't care what you pass for table as long as it supports the operations that are used inside of read(). This is what we call duck-typing: if it quacks like a duck, it's a duck. You see this in functions that act on sequeneces. For example:
def print_list(my_list):
for el in my_list:
print(el)
We can call print_list() with a list or a tuple:
print_list([1, 2, 3, 4])
print_list((1, 2, 3, 4))
In fact, anything that implements __iter__() and __next__() will work. This is the contract of the type and doesn't need to be specified with an interface, superclass, or generic type.
Now back to type hinting: there is a way to specify the "duck type contract" with type hinting, but I don't know the details off the top of my head. You could do some research to find out. As @juanpa.arrivillaga posted in a comment, you can look at typing.Protocol if you are interested in learning how to do the type hinting for cases like this.