**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
end_date: Optional[datetime] = None,
                           session: Session = None) -> List[TaskInstance]:
        """
        Get a set of task instance related to this task for a specific date
        range.
        """
        end_date = end_date or timezone.utcnow()
        return session.query(TaskInstance)\
            .filter(TaskInstance.dag_id == self.dag_id)\
            .filter(TaskInstance.task_id == self.task_id)\
            .filter(TaskInstance.execution_date >= start_date)\
            .filter(TaskInstance.execution_date <= end_date)\
            .order_by(TaskInstance.execution_date)\
            .all()
    def get_flat_relative_ids(self,