**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
**Example**: to run this task in a specific docker container through
        the KubernetesExecutor ::
            MyOperator(...,
                executor_config={
                    "KubernetesExecutor":
                        {"image": "myCustomDockerImage"}
                }
            )
    :type executor_config: dict
    :param do_xcom_push: if True, an XCom is pushed containing the Operator's
        result
    :type do_xcom_push: bool
    """
    
    template_fields: Iterable[str] = ()
    
    template_ext: Iterable[str] = ()
    
    ui_color = '#fff'  
    ui_fgcolor = '#000'  
    pool = ""  
    
    _base_operator_shallow_copy_attrs: Tuple[str, ...] = \
        ('user_defined_macros', 'user_defined_filters', 'params', '_log',)
    
    shallow_copy_attrs: Tuple[str, ...] = ()
    
    operator_extra_links: Iterable['BaseOperatorLink'] = ()
    
    __serialized_fields: Optional[FrozenSet[str]] = None