**Description**

Currently `BaseOperator` and `XComArgs` implements the same logic of `__lshift__`, `__rshift__` and others "chain" operations (`>>`, `<<`). It seems resonable to abstract this logic into `TaskMixin` to introduce some DRYness especially because the new concept of `TaskGroup` will also implement the same methods.

**Use case / motivation**

Limit duplication of logic.

**Related Issues**

https://github.com/apache/airflow/pull/10827#issuecomment-691927501
#10153 

airflow/models/baseoperator.py
"""
        Called for [Inlet] > [Operator] or [Operator] < [Inlet], so that if other is
        an attr annotated object it is set as an inlet to this operator
        """
        if not isinstance(other, Iterable):
            other = [other]
        for obj in other:
            if not attr.has(obj):
                raise TypeError(f"{obj} cannot be an inlet")
        self.add_inlets(other)
        return self
    def __setattr__(self, key, value):
        super().__setattr__(key, value)
        if self._lock_for_execution:
            
            return
        if self.__instantiated and key in self.template_fields:
            
            
            
            
            self.set_xcomargs_dependencies()
    def add_inlets(self, inlets: Iterable[Any]):