The Python documentation on Protocols (typing.Protocol) mentions the following: By default, protocol variables as defined above are considered readable and writable. To define a read-only protocol variable, one can use an (abstract) property Making a protocol variable read-only is useful because it becomes covariant. So for example: from typing import Protocol class A(): pass class B(A): pass # protocols class HasA(Protocol): a: A # read-write class HasA_RO(Protocol): @property def a(self) -> A: ... # read-only #implementation class Impl(): a: B Then Impl implements HasA_RO, but not HasA. This is because impl1: HasA = Impl() # type error impl2: HasA_RO = Impl() # ok a = A() impl1.a = a # valid for HasA, but not for Impl1 impl2.a = a # is, correctly, not allowed ! Now, I would like to know if there is a way to make a protocol with write-only variables. This would be useful because the variable would then be contravariant. For example class HasB_WO(Protocol): b: WriteOnly ... class Impl2(): b: A i2: HasB_WO = Impl2() # valid because you can always write a value of type B to a field of type A Continue reading...