isinstance is used to check whether something says it's a duck, regardless of whether or not it is a duck.
To answer your immediate question, isinstance.tee is a method, not a class, or type or tuple of types:
>>> type(itertools.tee)
<class 'builtin_function_or_method'>
(In fact, on my version of python, class has altogether been removed from th list of options). Python is a 'duck typed' language. Basically, in order for 'isinstance' to say that something is an instance of another thing, it must inherit from it in some way.
Example:
>>> type(str)
<class 'type'>
>>> s = "foo"
>>> isinstance(s,str)
True
>>> class myString(str): #myString inherits from str (a type)
... def __init__(self,s):
... super().__init__()
...
>>> s = myString("foo")
>>> s
'foo'
>>> isinstance(s,str)
True
Primarily, these base classes that are inherited should be (wherever possible) base types or abstract base classes. Why is this? Well, Python's developers want to avoid a situation where we have a million new user-types like FooString and BarInt that people start checking for instance of. This should be avoided.
The ABC's provide a way of allowing an object to say it is something, like an Integral, or a String, without (necessarily) having to be a string.
But, Python's duck typing is built on implementing protocols. Protocols are defined by one or more "special" (or magic or dunder) methods in the class. Determining what special methods are part of a class can be done with dir(myObj):
>>> dir(itertools.tee)
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__']
Or, even better, where possible, just try to do something with it, and if it fails, you know it's not a duck:
try: duck(something)
except: print("Not a duck!")