### Body

Currently `start_date` is mandatory parameter.
For DAGs with `schedule=None` we can relax this requirement as no scheduling calculation needed so the `start_date` parameter isn't used.

### Committer

- [X] I acknowledge that I am a maintainer/committer of the Apache Airflow project.
"""Verify tasks with Duplicate task_id raises error"""
        with pytest.raises(DuplicateTaskIdFound, match="Task id 't1' has already been added to the DAG"):
            dag = DAG("test_dag", start_date=DEFAULT_DATE)
            op1 = EmptyOperator(task_id="t1", dag=dag)
            op2 = EmptyOperator(task_id="t1", dag=dag)
            op1 >> op2
        assert dag.task_dict == {op1.task_id: op1}
    def test_duplicate_task_ids_for_same_task_is_allowed(self):
        """Verify that same tasks with Duplicate task_id do not raise error"""
        with DAG("test_dag", start_date=DEFAULT_DATE) as dag:
            op1 = op2 = EmptyOperator(task_id="t1")
            op3 = EmptyOperator(task_id="t3")
            op1 >> op3
            op2 >> op3
        assert op1 == op2
        assert dag.task_dict == {op1.task_id: op1, op3.task_id: op3}
        assert dag.task_dict == {op2.task_id: op2, op3.task_id: op3}
    def test_partial_subset_updates_all_references_while_deepcopy(self):
        with DAG("test_dag", start_date=DEFAULT_DATE) as dag:
            op1 = EmptyOperator(task_id="t1")
            op2 = EmptyOperator(task_id="t2")
            op3 = EmptyOperator(task_id="t3")
            op1 >> op2
            op2 >> op3
        partial = dag.partial_subset("t2", include_upstream=True, include_downstream=False)
        assert id(partial.task_dict["t1"].downstream_list[0].dag) == id(partial)
        
        assert "t3" not in partial.task_group.used_group_ids
    def test_partial_subset_taskgroup_join_ids(self):