type annotations are actual objects instantiated at runtime, usually only done at module import for non-local annotations but done each function invocation for locals. this is nice for extensibility as it makes interacting with and extending the type system as easy as writing any other normal python but in older versions of python it was extraordinarily slow, particularly with generics (as they were previously implemented by creating new actual typeobjects each time they had arguments applied (to be usable as baseclasses) - this has been corrected in 3.7 with the addition of __mro_entries__). 3.8 is however making annotations evaluated on demand not eagerly pretty much removing all runtime performance impact.