You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by po...@apache.org on 2021/12/31 15:53:42 UTC

[airflow] branch main updated: Even more typing in operators (template_fields/ext) (#20608)

This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 83f8e17  Even more typing in operators (template_fields/ext) (#20608)
83f8e17 is described below

commit 83f8e178ba7a3d4ca012c831a5bfc2cade9e812d
Author: Jarek Potiuk <ja...@potiuk.com>
AuthorDate: Fri Dec 31 16:53:09 2021 +0100

    Even more typing in operators (template_fields/ext) (#20608)
    
    Part of #19891
    There were few more places where I missed adding Sequence
    typing - including examples (also converted to tuples) and
    also template_ext. Also in a few places iterable was left
---
 airflow/decorators/python.py                       |  6 ++---
 airflow/decorators/python_virtualenv.py            |  6 ++---
 airflow/operators/bash.py                          |  6 ++---
 airflow/operators/email.py                         |  6 ++---
 airflow/operators/generic_transfer.py              |  6 ++---
 airflow/operators/sql.py                           | 28 +++++++++++-----------
 airflow/operators/trigger_dagrun.py                |  4 ++--
 airflow/providers/amazon/aws/operators/athena.py   |  2 +-
 .../amazon/aws/operators/cloud_formation.py        |  4 ++--
 airflow/providers/amazon/aws/operators/dms.py      | 10 ++++----
 airflow/providers/amazon/aws/operators/emr.py      |  8 +++----
 airflow/providers/amazon/aws/operators/glue.py     |  2 +-
 .../providers/amazon/aws/operators/redshift_sql.py |  2 +-
 airflow/providers/amazon/aws/operators/s3.py       |  2 +-
 .../providers/amazon/aws/operators/sagemaker.py    |  2 +-
 airflow/providers/amazon/aws/operators/sns.py      |  2 +-
 .../amazon/aws/operators/step_function.py          |  4 ++--
 airflow/providers/amazon/aws/sensors/athena.py     |  2 +-
 airflow/providers/amazon/aws/sensors/batch.py      |  2 +-
 airflow/providers/amazon/aws/sensors/dms.py        |  4 ++--
 airflow/providers/amazon/aws/sensors/emr.py        |  6 ++---
 airflow/providers/amazon/aws/sensors/sagemaker.py  |  8 +++----
 .../providers/amazon/aws/sensors/step_function.py  |  2 +-
 .../providers/amazon/aws/transfers/exasol_to_s3.py |  2 +-
 .../amazon/aws/transfers/google_api_to_s3.py       |  2 +-
 .../amazon/aws/transfers/hive_to_dynamodb.py       |  2 +-
 .../providers/amazon/aws/transfers/mysql_to_s3.py  |  2 +-
 .../amazon/aws/transfers/redshift_to_s3.py         |  2 +-
 .../amazon/aws/transfers/s3_to_redshift.py         |  2 +-
 .../amazon/aws/transfers/salesforce_to_s3.py       |  2 +-
 airflow/providers/apache/drill/operators/drill.py  |  2 +-
 airflow/providers/apache/druid/operators/druid.py  |  2 +-
 .../apache/druid/transfers/hive_to_druid.py        |  2 +-
 airflow/providers/apache/hive/operators/hive.py    |  2 +-
 .../apache/hive/transfers/hive_to_mysql.py         |  2 +-
 .../apache/hive/transfers/hive_to_samba.py         |  2 +-
 .../apache/hive/transfers/mssql_to_hive.py         |  2 +-
 .../apache/hive/transfers/mysql_to_hive.py         |  2 +-
 .../providers/apache/hive/transfers/s3_to_hive.py  |  2 +-
 .../apache/hive/transfers/vertica_to_hive.py       |  2 +-
 airflow/providers/apache/pig/operators/pig.py      |  2 +-
 .../providers/apache/spark/operators/spark_sql.py  |  2 +-
 .../cncf/kubernetes/operators/spark_kubernetes.py  |  2 +-
 airflow/providers/docker/decorators/docker.py      |  2 +-
 airflow/providers/docker/operators/docker.py       |  2 +-
 airflow/providers/exasol/operators/exasol.py       |  2 +-
 .../providers/google/cloud/operators/bigquery.py   |  8 +++----
 .../providers/google/cloud/operators/cloud_sql.py  |  2 +-
 .../providers/google/cloud/operators/spanner.py    |  6 ++---
 .../google/cloud/operators/stackdriver.py          |  4 ++--
 .../google/cloud/transfers/bigquery_to_bigquery.py |  2 +-
 .../google/cloud/transfers/bigquery_to_gcs.py      |  2 +-
 .../google/cloud/transfers/cassandra_to_gcs.py     |  2 +-
 .../google/cloud/transfers/gcs_to_bigquery.py      |  2 +-
 .../google/cloud/transfers/salesforce_to_gcs.py    |  2 +-
 .../providers/google/cloud/transfers/sql_to_gcs.py |  2 +-
 .../operators/campaign_manager.py                  |  2 +-
 .../marketing_platform/operators/display_video.py  |  2 +-
 .../marketing_platform/operators/search_ads.py     |  2 +-
 .../google/suite/transfers/sql_to_sheets.py        |  2 +-
 airflow/providers/http/operators/http.py           |  2 +-
 airflow/providers/jdbc/operators/jdbc.py           |  2 +-
 .../jenkins/operators/jenkins_job_trigger.py       |  2 +-
 airflow/providers/microsoft/azure/operators/adx.py |  2 +-
 .../providers/microsoft/mssql/operators/mssql.py   |  2 +-
 airflow/providers/mysql/operators/mysql.py         |  2 +-
 .../providers/mysql/transfers/presto_to_mysql.py   |  2 +-
 airflow/providers/mysql/transfers/s3_to_mysql.py   |  2 +-
 .../providers/mysql/transfers/trino_to_mysql.py    |  2 +-
 .../providers/mysql/transfers/vertica_to_mysql.py  |  2 +-
 airflow/providers/oracle/operators/oracle.py       |  2 +-
 airflow/providers/postgres/operators/postgres.py   |  2 +-
 airflow/providers/qubole/sensors/qubole.py         |  2 +-
 .../providers/singularity/operators/singularity.py |  2 +-
 airflow/providers/snowflake/operators/snowflake.py |  4 ++--
 .../snowflake/transfers/snowflake_to_slack.py      |  2 +-
 airflow/providers/sqlite/operators/sqlite.py       |  2 +-
 airflow/providers/ssh/operators/ssh.py             |  2 +-
 airflow/providers/vertica/operators/vertica.py     |  2 +-
 airflow/sensors/bash.py                            |  3 ++-
 airflow/sensors/date_time.py                       |  4 ++--
 airflow/sensors/filesystem.py                      |  3 ++-
 airflow/sensors/python.py                          |  4 ++--
 docs/apache-airflow/concepts/operators.rst         |  6 ++---
 docs/apache-airflow/howto/custom-operator.rst      | 10 ++++----
 tests/dags/test_only_dummy_tasks.py                |  3 ++-
 tests/models/test_dag.py                           |  6 ++---
 .../slack/operators/test_slack_webhook.py          |  3 ++-
 tests/test_utils/mock_operators.py                 |  4 ++--
 89 files changed, 150 insertions(+), 146 deletions(-)

diff --git a/airflow/decorators/python.py b/airflow/decorators/python.py
index 7dc6c1b..e082548 100644
--- a/airflow/decorators/python.py
+++ b/airflow/decorators/python.py
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-from typing import Callable, Optional, TypeVar
+from typing import Callable, Optional, Sequence, TypeVar
 
 from airflow.decorators.base import DecoratedOperator, task_decorator_factory
 from airflow.operators.python import PythonOperator
@@ -39,12 +39,12 @@ class _PythonDecoratedOperator(DecoratedOperator, PythonOperator):
     :type multiple_outputs: bool
     """
 
-    template_fields = ('op_args', 'op_kwargs')
+    template_fields: Sequence[str] = ('op_args', 'op_kwargs')
     template_fields_renderers = {"op_args": "py", "op_kwargs": "py"}
 
     # since we won't mutate the arguments, we should just do the shallow copy
     # there are some cases we can't deepcopy the objects (e.g protobuf).
-    shallow_copy_attrs = ('python_callable',)
+    shallow_copy_attrs: Sequence[str] = ('python_callable',)
 
     def __init__(
         self,
diff --git a/airflow/decorators/python_virtualenv.py b/airflow/decorators/python_virtualenv.py
index 8024e5a..15ecbde 100644
--- a/airflow/decorators/python_virtualenv.py
+++ b/airflow/decorators/python_virtualenv.py
@@ -17,7 +17,7 @@
 
 import inspect
 from textwrap import dedent
-from typing import Callable, Optional, TypeVar
+from typing import Callable, Optional, Sequence, TypeVar
 
 from airflow.decorators.base import DecoratedOperator, task_decorator_factory
 from airflow.operators.python import PythonVirtualenvOperator
@@ -42,12 +42,12 @@ class _PythonVirtualenvDecoratedOperator(DecoratedOperator, PythonVirtualenvOper
     :type multiple_outputs: bool
     """
 
-    template_fields = ('op_args', 'op_kwargs')
+    template_fields: Sequence[str] = ('op_args', 'op_kwargs')
     template_fields_renderers = {"op_args": "py", "op_kwargs": "py"}
 
     # since we won't mutate the arguments, we should just do the shallow copy
     # there are some cases we can't deepcopy the objects (e.g protobuf).
-    shallow_copy_attrs = ('python_callable',)
+    shallow_copy_attrs: Sequence[str] = ('python_callable',)
 
     def __init__(
         self,
diff --git a/airflow/operators/bash.py b/airflow/operators/bash.py
index cf4fdb3..7572143 100644
--- a/airflow/operators/bash.py
+++ b/airflow/operators/bash.py
@@ -16,7 +16,7 @@
 # specific language governing permissions and limitations
 # under the License.
 import os
-from typing import Dict, Optional
+from typing import Dict, Optional, Sequence
 
 from airflow.compat.functools import cached_property
 from airflow.exceptions import AirflowException, AirflowSkipException
@@ -128,9 +128,9 @@ class BashOperator(BaseOperator):
 
     """
 
-    template_fields = ('bash_command', 'env')
+    template_fields: Sequence[str] = ('bash_command', 'env')
     template_fields_renderers = {'bash_command': 'bash', 'env': 'json'}
-    template_ext = (
+    template_ext: Sequence[str] = (
         '.sh',
         '.bash',
     )
diff --git a/airflow/operators/email.py b/airflow/operators/email.py
index cc5d079..c8cb61b 100644
--- a/airflow/operators/email.py
+++ b/airflow/operators/email.py
@@ -15,7 +15,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Dict, List, Optional, Sequence, Union
 
 from airflow.models import BaseOperator
 from airflow.utils.context import Context
@@ -48,9 +48,9 @@ class EmailOperator(BaseOperator):
     :type custom_headers: dict
     """
 
-    template_fields = ('to', 'subject', 'html_content', 'files')
+    template_fields: Sequence[str] = ('to', 'subject', 'html_content', 'files')
     template_fields_renderers = {"html_content": "html"}
-    template_ext = ('.html',)
+    template_ext: Sequence[str] = ('.html',)
     ui_color = '#e6faf9'
 
     def __init__(
diff --git a/airflow/operators/generic_transfer.py b/airflow/operators/generic_transfer.py
index 1f7cf40..e38f648 100644
--- a/airflow/operators/generic_transfer.py
+++ b/airflow/operators/generic_transfer.py
@@ -15,7 +15,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-from typing import List, Optional, Union
+from typing import List, Optional, Sequence, Union
 
 from airflow.hooks.base import BaseHook
 from airflow.models import BaseOperator
@@ -46,8 +46,8 @@ class GenericTransfer(BaseOperator):
     :type insert_args: dict
     """
 
-    template_fields = ('sql', 'destination_table', 'preoperator')
-    template_ext = (
+    template_fields: Sequence[str] = ('sql', 'destination_table', 'preoperator')
+    template_ext: Sequence[str] = (
         '.sql',
         '.hql',
     )
diff --git a/airflow/operators/sql.py b/airflow/operators/sql.py
index ba3641b..b642772 100644
--- a/airflow/operators/sql.py
+++ b/airflow/operators/sql.py
@@ -15,7 +15,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-from typing import Any, Dict, Iterable, List, Mapping, Optional, SupportsAbs, Union
+from typing import Any, Dict, Iterable, List, Mapping, Optional, Sequence, SupportsAbs, Union
 
 from airflow.compat.functools import cached_property
 from airflow.exceptions import AirflowException
@@ -124,8 +124,8 @@ class SQLCheckOperator(BaseSQLOperator):
     :type database: str
     """
 
-    template_fields: Iterable[str] = ("sql",)
-    template_ext: Iterable[str] = (
+    template_fields: Sequence[str] = ("sql",)
+    template_ext: Sequence[str] = (
         ".hql",
         ".sql",
     )
@@ -178,14 +178,14 @@ class SQLValueCheckOperator(BaseSQLOperator):
     """
 
     __mapper_args__ = {"polymorphic_identity": "SQLValueCheckOperator"}
-    template_fields = (
+    template_fields: Sequence[str] = (
         "sql",
         "pass_value",
-    )  # type: Iterable[str]
-    template_ext = (
+    )
+    template_ext: Sequence[str] = (
         ".hql",
         ".sql",
-    )  # type: Iterable[str]
+    )
     ui_color = "#fff7e6"
 
     def __init__(
@@ -289,8 +289,8 @@ class SQLIntervalCheckOperator(BaseSQLOperator):
     """
 
     __mapper_args__ = {"polymorphic_identity": "SQLIntervalCheckOperator"}
-    template_fields: Iterable[str] = ("sql1", "sql2")
-    template_ext: Iterable[str] = (
+    template_fields: Sequence[str] = ("sql1", "sql2")
+    template_ext: Sequence[str] = (
         ".hql",
         ".sql",
     )
@@ -418,11 +418,11 @@ class SQLThresholdCheckOperator(BaseSQLOperator):
     :type max_threshold: numeric or str
     """
 
-    template_fields = ("sql", "min_threshold", "max_threshold")
-    template_ext = (
+    template_fields: Sequence[str] = ("sql", "min_threshold", "max_threshold")
+    template_ext: Sequence[str] = (
         ".hql",
         ".sql",
-    )  # type: Iterable[str]
+    )
 
     def __init__(
         self,
@@ -505,8 +505,8 @@ class BranchSQLOperator(BaseSQLOperator, SkipMixin):
     :type parameters: mapping or iterable
     """
 
-    template_fields = ("sql",)
-    template_ext = (".sql",)
+    template_fields: Sequence[str] = ("sql",)
+    template_ext: Sequence[str] = (".sql",)
     ui_color = "#a22034"
     ui_fgcolor = "#F7F7F7"
 
diff --git a/airflow/operators/trigger_dagrun.py b/airflow/operators/trigger_dagrun.py
index 1e668ce..c14f2d4 100644
--- a/airflow/operators/trigger_dagrun.py
+++ b/airflow/operators/trigger_dagrun.py
@@ -19,7 +19,7 @@
 import datetime
 import json
 import time
-from typing import Dict, List, Optional, Union
+from typing import Dict, List, Optional, Sequence, Union
 
 from airflow.api.common.trigger_dag import trigger_dag
 from airflow.exceptions import AirflowException, DagNotFound, DagRunAlreadyExists
@@ -83,7 +83,7 @@ class TriggerDagRunOperator(BaseOperator):
     :type failed_states: list
     """
 
-    template_fields = ("trigger_dag_id", "trigger_run_id", "execution_date", "conf")
+    template_fields: Sequence[str] = ("trigger_dag_id", "trigger_run_id", "execution_date", "conf")
     template_fields_renderers = {"conf": "py"}
     ui_color = "#ffefeb"
 
diff --git a/airflow/providers/amazon/aws/operators/athena.py b/airflow/providers/amazon/aws/operators/athena.py
index 0f257e4..7e0c814 100644
--- a/airflow/providers/amazon/aws/operators/athena.py
+++ b/airflow/providers/amazon/aws/operators/athena.py
@@ -65,7 +65,7 @@ class AthenaOperator(BaseOperator):
 
     ui_color = '#44b5e2'
     template_fields: Sequence[str] = ('query', 'database', 'output_location')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     template_fields_renderers = {"query": "sql"}
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/operators/cloud_formation.py b/airflow/providers/amazon/aws/operators/cloud_formation.py
index 0a41358..6a3cc32 100644
--- a/airflow/providers/amazon/aws/operators/cloud_formation.py
+++ b/airflow/providers/amazon/aws/operators/cloud_formation.py
@@ -41,7 +41,7 @@ class CloudFormationCreateStackOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('stack_name',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#6b9659'
 
     def __init__(self, *, stack_name: str, params: dict, aws_conn_id: str = 'aws_default', **kwargs):
@@ -73,7 +73,7 @@ class CloudFormationDeleteStackOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('stack_name',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#1d472b'
     ui_fgcolor = '#FFF'
 
diff --git a/airflow/providers/amazon/aws/operators/dms.py b/airflow/providers/amazon/aws/operators/dms.py
index 5dabdb8..0ff719a 100644
--- a/airflow/providers/amazon/aws/operators/dms.py
+++ b/airflow/providers/amazon/aws/operators/dms.py
@@ -65,7 +65,7 @@ class DmsCreateTaskOperator(BaseOperator):
         'migration_type',
         'create_task_kwargs',
     )
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     template_fields_renderers = {
         "table_mappings": "json",
         "create_task_kwargs": "json",
@@ -135,7 +135,7 @@ class DmsDeleteTaskOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('replication_task_arn',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     template_fields_renderers: Dict[str, str] = {}
 
     def __init__(
@@ -175,7 +175,7 @@ class DmsDescribeTasksOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('describe_tasks_kwargs',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     template_fields_renderers: Dict[str, str] = {'describe_tasks_kwargs': 'json'}
 
     def __init__(
@@ -228,7 +228,7 @@ class DmsStartTaskOperator(BaseOperator):
         'start_replication_task_type',
         'start_task_kwargs',
     )
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     template_fields_renderers = {'start_task_kwargs': 'json'}
 
     def __init__(
@@ -277,7 +277,7 @@ class DmsStopTaskOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('replication_task_arn',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     template_fields_renderers: Dict[str, str] = {}
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/operators/emr.py b/airflow/providers/amazon/aws/operators/emr.py
index e4be273..31abb03 100644
--- a/airflow/providers/amazon/aws/operators/emr.py
+++ b/airflow/providers/amazon/aws/operators/emr.py
@@ -60,7 +60,7 @@ class EmrAddStepsOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('job_flow_id', 'job_flow_name', 'cluster_states', 'steps')
-    template_ext = ('.json',)
+    template_ext: Sequence[str] = ('.json',)
     template_fields_renderers = {"steps": "json"}
     ui_color = '#f9c915'
 
@@ -281,7 +281,7 @@ class EmrCreateJobFlowOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('job_flow_overrides',)
-    template_ext = ('.json',)
+    template_ext: Sequence[str] = ('.json',)
     template_fields_renderers = {"job_flow_overrides": "json"}
     ui_color = '#f9c915'
     operator_extra_links = (EmrClusterLink(),)
@@ -340,7 +340,7 @@ class EmrModifyClusterOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('cluster_id', 'step_concurrency_level')
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#f9c915'
 
     def __init__(
@@ -384,7 +384,7 @@ class EmrTerminateJobFlowOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('job_flow_id',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#f9c915'
 
     def __init__(self, *, job_flow_id: str, aws_conn_id: str = 'aws_default', **kwargs):
diff --git a/airflow/providers/amazon/aws/operators/glue.py b/airflow/providers/amazon/aws/operators/glue.py
index f33af8c..2ea0eb1 100644
--- a/airflow/providers/amazon/aws/operators/glue.py
+++ b/airflow/providers/amazon/aws/operators/glue.py
@@ -63,7 +63,7 @@ class GlueJobOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('script_args',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     template_fields_renderers = {
         "script_args": "json",
         "create_job_kwargs": "json",
diff --git a/airflow/providers/amazon/aws/operators/redshift_sql.py b/airflow/providers/amazon/aws/operators/redshift_sql.py
index 7bafa10..a3cd3f9 100644
--- a/airflow/providers/amazon/aws/operators/redshift_sql.py
+++ b/airflow/providers/amazon/aws/operators/redshift_sql.py
@@ -46,7 +46,7 @@ class RedshiftSQLOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
 
     def __init__(
         self,
diff --git a/airflow/providers/amazon/aws/operators/s3.py b/airflow/providers/amazon/aws/operators/s3.py
index 957b496..95f4b54 100644
--- a/airflow/providers/amazon/aws/operators/s3.py
+++ b/airflow/providers/amazon/aws/operators/s3.py
@@ -461,7 +461,7 @@ class S3FileTransformOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('source_s3_key', 'dest_s3_key', 'script_args')
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#f9c915'
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/operators/sagemaker.py b/airflow/providers/amazon/aws/operators/sagemaker.py
index ce77f21..48d5842 100644
--- a/airflow/providers/amazon/aws/operators/sagemaker.py
+++ b/airflow/providers/amazon/aws/operators/sagemaker.py
@@ -45,7 +45,7 @@ class SageMakerBaseOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('config',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     template_fields_renderers = {'config': 'json'}
     ui_color = '#ededed'
     integer_fields = []
diff --git a/airflow/providers/amazon/aws/operators/sns.py b/airflow/providers/amazon/aws/operators/sns.py
index eb07cb7..8cd28d0 100644
--- a/airflow/providers/amazon/aws/operators/sns.py
+++ b/airflow/providers/amazon/aws/operators/sns.py
@@ -44,7 +44,7 @@ class SnsPublishOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('message', 'subject', 'message_attributes')
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     template_fields_renderers = {"message_attributes": "json"}
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/operators/step_function.py b/airflow/providers/amazon/aws/operators/step_function.py
index aa2bf59..b30653e 100644
--- a/airflow/providers/amazon/aws/operators/step_function.py
+++ b/airflow/providers/amazon/aws/operators/step_function.py
@@ -49,7 +49,7 @@ class StepFunctionStartExecutionOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('state_machine_arn', 'name', 'input')
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#f9c915'
 
     def __init__(
@@ -98,7 +98,7 @@ class StepFunctionGetExecutionOutputOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('execution_arn',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#f9c915'
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/sensors/athena.py b/airflow/providers/amazon/aws/sensors/athena.py
index c585bb3..dae4be4 100644
--- a/airflow/providers/amazon/aws/sensors/athena.py
+++ b/airflow/providers/amazon/aws/sensors/athena.py
@@ -59,7 +59,7 @@ class AthenaSensor(BaseSensorOperator):
     SUCCESS_STATES = ('SUCCEEDED',)
 
     template_fields: Sequence[str] = ('query_execution_id',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#66c3ff'
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/sensors/batch.py b/airflow/providers/amazon/aws/sensors/batch.py
index f9db170..10b1c7a 100644
--- a/airflow/providers/amazon/aws/sensors/batch.py
+++ b/airflow/providers/amazon/aws/sensors/batch.py
@@ -37,7 +37,7 @@ class BatchSensor(BaseSensorOperator):
     """
 
     template_fields: Sequence[str] = ('job_id',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#66c3ff'
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/sensors/dms.py b/airflow/providers/amazon/aws/sensors/dms.py
index 81bef67..fb88082 100644
--- a/airflow/providers/amazon/aws/sensors/dms.py
+++ b/airflow/providers/amazon/aws/sensors/dms.py
@@ -45,7 +45,7 @@ class DmsTaskBaseSensor(BaseSensorOperator):
     """
 
     template_fields: Sequence[str] = ('replication_task_arn',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
 
     def __init__(
         self,
@@ -103,7 +103,7 @@ class DmsTaskCompletedSensor(DmsTaskBaseSensor):
     """
 
     template_fields: Sequence[str] = ('replication_task_arn',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
diff --git a/airflow/providers/amazon/aws/sensors/emr.py b/airflow/providers/amazon/aws/sensors/emr.py
index 7353b89..c7ecee2 100644
--- a/airflow/providers/amazon/aws/sensors/emr.py
+++ b/airflow/providers/amazon/aws/sensors/emr.py
@@ -150,7 +150,7 @@ class EmrContainerSensor(BaseSensorOperator):
     SUCCESS_STATES = ("COMPLETED",)
 
     template_fields: Sequence[str] = ('virtual_cluster_id', 'job_id')
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#66c3ff'
 
     def __init__(
@@ -207,7 +207,7 @@ class EmrJobFlowSensor(EmrBaseSensor):
     """
 
     template_fields: Sequence[str] = ('job_flow_id', 'target_states', 'failed_states')
-    template_ext = ()
+    template_ext: Sequence[str] = ()
 
     def __init__(
         self,
@@ -288,7 +288,7 @@ class EmrStepSensor(EmrBaseSensor):
     """
 
     template_fields: Sequence[str] = ('job_flow_id', 'step_id', 'target_states', 'failed_states')
-    template_ext = ()
+    template_ext: Sequence[str] = ()
 
     def __init__(
         self,
diff --git a/airflow/providers/amazon/aws/sensors/sagemaker.py b/airflow/providers/amazon/aws/sensors/sagemaker.py
index 69c7931..184ee93 100644
--- a/airflow/providers/amazon/aws/sensors/sagemaker.py
+++ b/airflow/providers/amazon/aws/sensors/sagemaker.py
@@ -95,7 +95,7 @@ class SageMakerEndpointSensor(SageMakerBaseSensor):
     """
 
     template_fields: Sequence[str] = ('endpoint_name',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
 
     def __init__(self, *, endpoint_name, **kwargs):
         super().__init__(**kwargs)
@@ -132,7 +132,7 @@ class SageMakerTransformSensor(SageMakerBaseSensor):
     """
 
     template_fields: Sequence[str] = ('job_name',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
 
     def __init__(self, *, job_name: str, **kwargs):
         super().__init__(**kwargs)
@@ -169,7 +169,7 @@ class SageMakerTuningSensor(SageMakerBaseSensor):
     """
 
     template_fields: Sequence[str] = ('job_name',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
 
     def __init__(self, *, job_name: str, **kwargs):
         super().__init__(**kwargs)
@@ -206,7 +206,7 @@ class SageMakerTrainingSensor(SageMakerBaseSensor):
     """
 
     template_fields: Sequence[str] = ('job_name',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
 
     def __init__(self, *, job_name, print_log=True, **kwargs):
         super().__init__(**kwargs)
diff --git a/airflow/providers/amazon/aws/sensors/step_function.py b/airflow/providers/amazon/aws/sensors/step_function.py
index 0a534c1..bbad9da 100644
--- a/airflow/providers/amazon/aws/sensors/step_function.py
+++ b/airflow/providers/amazon/aws/sensors/step_function.py
@@ -50,7 +50,7 @@ class StepFunctionExecutionSensor(BaseSensorOperator):
     SUCCESS_STATES = ('SUCCEEDED',)
 
     template_fields: Sequence[str] = ('execution_arn',)
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#66c3ff'
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/transfers/exasol_to_s3.py b/airflow/providers/amazon/aws/transfers/exasol_to_s3.py
index d3ccf1b..b9c1d4f 100644
--- a/airflow/providers/amazon/aws/transfers/exasol_to_s3.py
+++ b/airflow/providers/amazon/aws/transfers/exasol_to_s3.py
@@ -60,7 +60,7 @@ class ExasolToS3Operator(BaseOperator):
 
     template_fields: Sequence[str] = ('query_or_table', 'key', 'bucket_name', 'query_params', 'export_params')
     template_fields_renderers = {"query_or_table": "sql", "query_params": "json", "export_params": "json"}
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#ededed'
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/transfers/google_api_to_s3.py b/airflow/providers/amazon/aws/transfers/google_api_to_s3.py
index bfc45e8..af979ee 100644
--- a/airflow/providers/amazon/aws/transfers/google_api_to_s3.py
+++ b/airflow/providers/amazon/aws/transfers/google_api_to_s3.py
@@ -100,7 +100,7 @@ class GoogleApiToS3Operator(BaseOperator):
         's3_destination_key',
         'google_impersonation_chain',
     )
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#cc181e'
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/transfers/hive_to_dynamodb.py b/airflow/providers/amazon/aws/transfers/hive_to_dynamodb.py
index fb27e62..2bbf99e 100644
--- a/airflow/providers/amazon/aws/transfers/hive_to_dynamodb.py
+++ b/airflow/providers/amazon/aws/transfers/hive_to_dynamodb.py
@@ -59,7 +59,7 @@ class HiveToDynamoDBOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#a0e08c'
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/transfers/mysql_to_s3.py b/airflow/providers/amazon/aws/transfers/mysql_to_s3.py
index 905160a..72e28d7 100644
--- a/airflow/providers/amazon/aws/transfers/mysql_to_s3.py
+++ b/airflow/providers/amazon/aws/transfers/mysql_to_s3.py
@@ -94,7 +94,7 @@ class MySQLToS3Operator(BaseOperator):
         's3_key',
         'query',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     template_fields_renderers = {
         "query": "sql",
         "pd_csv_kwargs": "json",
diff --git a/airflow/providers/amazon/aws/transfers/redshift_to_s3.py b/airflow/providers/amazon/aws/transfers/redshift_to_s3.py
index 24a67a5..afb5738 100644
--- a/airflow/providers/amazon/aws/transfers/redshift_to_s3.py
+++ b/airflow/providers/amazon/aws/transfers/redshift_to_s3.py
@@ -84,7 +84,7 @@ class RedshiftToS3Operator(BaseOperator):
         'unload_options',
         'select_query',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     template_fields_renderers = {'select_query': 'sql'}
     ui_color = '#ededed'
 
diff --git a/airflow/providers/amazon/aws/transfers/s3_to_redshift.py b/airflow/providers/amazon/aws/transfers/s3_to_redshift.py
index cec6cee..ee65848 100644
--- a/airflow/providers/amazon/aws/transfers/s3_to_redshift.py
+++ b/airflow/providers/amazon/aws/transfers/s3_to_redshift.py
@@ -76,7 +76,7 @@ class S3ToRedshiftOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('s3_bucket', 's3_key', 'schema', 'table', 'column_list', 'copy_options')
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#99e699'
 
     def __init__(
diff --git a/airflow/providers/amazon/aws/transfers/salesforce_to_s3.py b/airflow/providers/amazon/aws/transfers/salesforce_to_s3.py
index 19fcfd5..4ba3630 100644
--- a/airflow/providers/amazon/aws/transfers/salesforce_to_s3.py
+++ b/airflow/providers/amazon/aws/transfers/salesforce_to_s3.py
@@ -73,7 +73,7 @@ class SalesforceToS3Operator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ("salesforce_query", "s3_bucket_name", "s3_key")
-    template_ext = (".sql",)
+    template_ext: Sequence[str] = (".sql",)
     template_fields_renderers = {"salesforce_query": "sql"}
 
     def __init__(
diff --git a/airflow/providers/apache/drill/operators/drill.py b/airflow/providers/apache/drill/operators/drill.py
index aaa1923..9c3981d 100644
--- a/airflow/providers/apache/drill/operators/drill.py
+++ b/airflow/providers/apache/drill/operators/drill.py
@@ -47,7 +47,7 @@ class DrillOperator(BaseOperator):
 
     template_fields: Sequence[str] = ('sql',)
     template_fields_renderers = {'sql': 'sql'}
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#ededed'
 
     def __init__(
diff --git a/airflow/providers/apache/druid/operators/druid.py b/airflow/providers/apache/druid/operators/druid.py
index ab3c989..333c239 100644
--- a/airflow/providers/apache/druid/operators/druid.py
+++ b/airflow/providers/apache/druid/operators/druid.py
@@ -42,7 +42,7 @@ class DruidOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('json_index_file',)
-    template_ext = ('.json',)
+    template_ext: Sequence[str] = ('.json',)
     template_fields_renderers = {'json_index_file': 'json'}
 
     def __init__(
diff --git a/airflow/providers/apache/druid/transfers/hive_to_druid.py b/airflow/providers/apache/druid/transfers/hive_to_druid.py
index 6e8a02d..e728b4a 100644
--- a/airflow/providers/apache/druid/transfers/hive_to_druid.py
+++ b/airflow/providers/apache/druid/transfers/hive_to_druid.py
@@ -80,7 +80,7 @@ class HiveToDruidOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql', 'intervals')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
 
     def __init__(
         self,
diff --git a/airflow/providers/apache/hive/operators/hive.py b/airflow/providers/apache/hive/operators/hive.py
index db36c00..4672091 100644
--- a/airflow/providers/apache/hive/operators/hive.py
+++ b/airflow/providers/apache/hive/operators/hive.py
@@ -74,7 +74,7 @@ class HiveOperator(BaseOperator):
         'mapred_job_name',
         'mapred_queue_priority',
     )
-    template_ext = (
+    template_ext: Sequence[str] = (
         '.hql',
         '.sql',
     )
diff --git a/airflow/providers/apache/hive/transfers/hive_to_mysql.py b/airflow/providers/apache/hive/transfers/hive_to_mysql.py
index 524b0cb..1789ec5 100644
--- a/airflow/providers/apache/hive/transfers/hive_to_mysql.py
+++ b/airflow/providers/apache/hive/transfers/hive_to_mysql.py
@@ -64,7 +64,7 @@ class HiveToMySqlOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql', 'mysql_table', 'mysql_preoperator', 'mysql_postoperator')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#a0e08c'
 
     def __init__(
diff --git a/airflow/providers/apache/hive/transfers/hive_to_samba.py b/airflow/providers/apache/hive/transfers/hive_to_samba.py
index 49c45be..41bed4f 100644
--- a/airflow/providers/apache/hive/transfers/hive_to_samba.py
+++ b/airflow/providers/apache/hive/transfers/hive_to_samba.py
@@ -47,7 +47,7 @@ class HiveToSambaOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('hql', 'destination_filepath')
-    template_ext = (
+    template_ext: Sequence[str] = (
         '.hql',
         '.sql',
     )
diff --git a/airflow/providers/apache/hive/transfers/mssql_to_hive.py b/airflow/providers/apache/hive/transfers/mssql_to_hive.py
index 823d684..db0125c 100644
--- a/airflow/providers/apache/hive/transfers/mssql_to_hive.py
+++ b/airflow/providers/apache/hive/transfers/mssql_to_hive.py
@@ -73,7 +73,7 @@ class MsSqlToHiveOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql', 'partition', 'hive_table')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#a0e08c'
 
     def __init__(
diff --git a/airflow/providers/apache/hive/transfers/mysql_to_hive.py b/airflow/providers/apache/hive/transfers/mysql_to_hive.py
index 8b3ac85..b2fd51e 100644
--- a/airflow/providers/apache/hive/transfers/mysql_to_hive.py
+++ b/airflow/providers/apache/hive/transfers/mysql_to_hive.py
@@ -81,7 +81,7 @@ class MySqlToHiveOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql', 'partition', 'hive_table')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#a0e08c'
 
     def __init__(
diff --git a/airflow/providers/apache/hive/transfers/s3_to_hive.py b/airflow/providers/apache/hive/transfers/s3_to_hive.py
index 2807266..8362954 100644
--- a/airflow/providers/apache/hive/transfers/s3_to_hive.py
+++ b/airflow/providers/apache/hive/transfers/s3_to_hive.py
@@ -103,7 +103,7 @@ class S3ToHiveOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('s3_key', 'partition', 'hive_table')
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#a0e08c'
 
     def __init__(
diff --git a/airflow/providers/apache/hive/transfers/vertica_to_hive.py b/airflow/providers/apache/hive/transfers/vertica_to_hive.py
index 16900bd..7f26368 100644
--- a/airflow/providers/apache/hive/transfers/vertica_to_hive.py
+++ b/airflow/providers/apache/hive/transfers/vertica_to_hive.py
@@ -69,7 +69,7 @@ class VerticaToHiveOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql', 'partition', 'hive_table')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#b4e0ff'
 
     def __init__(
diff --git a/airflow/providers/apache/pig/operators/pig.py b/airflow/providers/apache/pig/operators/pig.py
index 9e23cb3..834c8ad 100644
--- a/airflow/providers/apache/pig/operators/pig.py
+++ b/airflow/providers/apache/pig/operators/pig.py
@@ -44,7 +44,7 @@ class PigOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('pig',)
-    template_ext = (
+    template_ext: Sequence[str] = (
         '.pig',
         '.piglatin',
     )
diff --git a/airflow/providers/apache/spark/operators/spark_sql.py b/airflow/providers/apache/spark/operators/spark_sql.py
index 5dd2496..f9a00fc 100644
--- a/airflow/providers/apache/spark/operators/spark_sql.py
+++ b/airflow/providers/apache/spark/operators/spark_sql.py
@@ -64,7 +64,7 @@ class SparkSqlOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('_sql',)
-    template_ext = [".sql", ".hql"]
+    template_ext: Sequence[str] = (".sql", ".hql")
 
     def __init__(
         self,
diff --git a/airflow/providers/cncf/kubernetes/operators/spark_kubernetes.py b/airflow/providers/cncf/kubernetes/operators/spark_kubernetes.py
index 567b788..bdf0cc8 100644
--- a/airflow/providers/cncf/kubernetes/operators/spark_kubernetes.py
+++ b/airflow/providers/cncf/kubernetes/operators/spark_kubernetes.py
@@ -47,7 +47,7 @@ class SparkKubernetesOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('application_file', 'namespace')
-    template_ext = ('.yaml', '.yml', '.json')
+    template_ext: Sequence[str] = ('.yaml', '.yml', '.json')
     ui_color = '#f4a460'
 
     def __init__(
diff --git a/airflow/providers/docker/decorators/docker.py b/airflow/providers/docker/decorators/docker.py
index 8870b08..3eb3182 100644
--- a/airflow/providers/docker/decorators/docker.py
+++ b/airflow/providers/docker/decorators/docker.py
@@ -69,7 +69,7 @@ class _DockerDecoratedOperator(DecoratedOperator, DockerOperator):
 
     # since we won't mutate the arguments, we should just do the shallow copy
     # there are some cases we can't deepcopy the objects (e.g protobuf).
-    shallow_copy_attrs = ('python_callable',)
+    shallow_copy_attrs: Sequence[str] = ('python_callable',)
 
     def __init__(
         self,
diff --git a/airflow/providers/docker/operators/docker.py b/airflow/providers/docker/operators/docker.py
index b49c755..7fe7456 100644
--- a/airflow/providers/docker/operators/docker.py
+++ b/airflow/providers/docker/operators/docker.py
@@ -156,7 +156,7 @@ class DockerOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('image', 'command', 'environment', 'container_name')
-    template_ext = (
+    template_ext: Sequence[str] = (
         '.sh',
         '.bash',
     )
diff --git a/airflow/providers/exasol/operators/exasol.py b/airflow/providers/exasol/operators/exasol.py
index 0fddab1..d75cfb6 100644
--- a/airflow/providers/exasol/operators/exasol.py
+++ b/airflow/providers/exasol/operators/exasol.py
@@ -44,7 +44,7 @@ class ExasolOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#ededed'
 
     def __init__(
diff --git a/airflow/providers/google/cloud/operators/bigquery.py b/airflow/providers/google/cloud/operators/bigquery.py
index d8aa6b3..a6b0b52 100644
--- a/airflow/providers/google/cloud/operators/bigquery.py
+++ b/airflow/providers/google/cloud/operators/bigquery.py
@@ -170,7 +170,7 @@ class BigQueryCheckOperator(_BigQueryDbHookMixin, SQLCheckOperator):
         'impersonation_chain',
         'labels',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = BigQueryUIColors.CHECK.value
 
     def __init__(
@@ -239,7 +239,7 @@ class BigQueryValueCheckOperator(_BigQueryDbHookMixin, SQLValueCheckOperator):
         'impersonation_chain',
         'labels',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = BigQueryUIColors.CHECK.value
 
     def __init__(
@@ -604,7 +604,7 @@ class BigQueryExecuteQueryOperator(BaseOperator):
         'query_params',
         'impersonation_chain',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = BigQueryUIColors.QUERY.value
 
     @property
@@ -2214,7 +2214,7 @@ class BigQueryInsertJobOperator(BaseOperator):
         "job_id",
         "impersonation_chain",
     )
-    template_ext = (".json",)
+    template_ext: Sequence[str] = (".json",)
     template_fields_renderers = {"configuration": "json", "configuration.query.query": "sql"}
     ui_color = BigQueryUIColors.QUERY.value
 
diff --git a/airflow/providers/google/cloud/operators/cloud_sql.py b/airflow/providers/google/cloud/operators/cloud_sql.py
index 9478975..2db9996 100644
--- a/airflow/providers/google/cloud/operators/cloud_sql.py
+++ b/airflow/providers/google/cloud/operators/cloud_sql.py
@@ -1025,7 +1025,7 @@ class CloudSQLExecuteQueryOperator(BaseOperator):
 
     # [START gcp_sql_query_template_fields]
     template_fields: Sequence[str] = ('sql', 'gcp_cloudsql_conn_id', 'gcp_conn_id')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     # [END gcp_sql_query_template_fields]
 
     def __init__(
diff --git a/airflow/providers/google/cloud/operators/spanner.py b/airflow/providers/google/cloud/operators/spanner.py
index 3cb2efc..e41e527 100644
--- a/airflow/providers/google/cloud/operators/spanner.py
+++ b/airflow/providers/google/cloud/operators/spanner.py
@@ -237,7 +237,7 @@ class SpannerQueryDatabaseInstanceOperator(BaseOperator):
         'gcp_conn_id',
         'impersonation_chain',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     # [END gcp_spanner_query_template_fields]
 
     def __init__(
@@ -346,7 +346,7 @@ class SpannerDeployDatabaseInstanceOperator(BaseOperator):
         'gcp_conn_id',
         'impersonation_chain',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     # [END gcp_spanner_database_deploy_template_fields]
 
     def __init__(
@@ -450,7 +450,7 @@ class SpannerUpdateDatabaseInstanceOperator(BaseOperator):
         'gcp_conn_id',
         'impersonation_chain',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     # [END gcp_spanner_database_update_template_fields]
 
     def __init__(
diff --git a/airflow/providers/google/cloud/operators/stackdriver.py b/airflow/providers/google/cloud/operators/stackdriver.py
index b07c9e1..8a679de 100644
--- a/airflow/providers/google/cloud/operators/stackdriver.py
+++ b/airflow/providers/google/cloud/operators/stackdriver.py
@@ -379,7 +379,7 @@ class StackdriverUpsertAlertOperator(BaseOperator):
         'alerts',
         'impersonation_chain',
     )
-    template_ext = ('.json',)
+    template_ext: Sequence[str] = ('.json',)
 
     ui_color = "#e5ffcc"
 
@@ -868,7 +868,7 @@ class StackdriverUpsertNotificationChannelOperator(BaseOperator):
         'channels',
         'impersonation_chain',
     )
-    template_ext = ('.json',)
+    template_ext: Sequence[str] = ('.json',)
 
     ui_color = "#e5ffcc"
 
diff --git a/airflow/providers/google/cloud/transfers/bigquery_to_bigquery.py b/airflow/providers/google/cloud/transfers/bigquery_to_bigquery.py
index 45fd538..dca5b49 100644
--- a/airflow/providers/google/cloud/transfers/bigquery_to_bigquery.py
+++ b/airflow/providers/google/cloud/transfers/bigquery_to_bigquery.py
@@ -85,7 +85,7 @@ class BigQueryToBigQueryOperator(BaseOperator):
         'labels',
         'impersonation_chain',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#e6f0e4'
 
     def __init__(
diff --git a/airflow/providers/google/cloud/transfers/bigquery_to_gcs.py b/airflow/providers/google/cloud/transfers/bigquery_to_gcs.py
index af4596b..80bf348 100644
--- a/airflow/providers/google/cloud/transfers/bigquery_to_gcs.py
+++ b/airflow/providers/google/cloud/transfers/bigquery_to_gcs.py
@@ -85,7 +85,7 @@ class BigQueryToGCSOperator(BaseOperator):
         'labels',
         'impersonation_chain',
     )
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#e4e6f0'
 
     def __init__(
diff --git a/airflow/providers/google/cloud/transfers/cassandra_to_gcs.py b/airflow/providers/google/cloud/transfers/cassandra_to_gcs.py
index fbb4f71..34aeb03 100644
--- a/airflow/providers/google/cloud/transfers/cassandra_to_gcs.py
+++ b/airflow/providers/google/cloud/transfers/cassandra_to_gcs.py
@@ -103,7 +103,7 @@ class CassandraToGCSOperator(BaseOperator):
         'schema_filename',
         'impersonation_chain',
     )
-    template_ext = ('.cql',)
+    template_ext: Sequence[str] = ('.cql',)
     ui_color = '#a0e08c'
 
     def __init__(
diff --git a/airflow/providers/google/cloud/transfers/gcs_to_bigquery.py b/airflow/providers/google/cloud/transfers/gcs_to_bigquery.py
index 365faf7..e238bb3 100644
--- a/airflow/providers/google/cloud/transfers/gcs_to_bigquery.py
+++ b/airflow/providers/google/cloud/transfers/gcs_to_bigquery.py
@@ -170,7 +170,7 @@ class GCSToBigQueryOperator(BaseOperator):
         'destination_project_dataset_table',
         'impersonation_chain',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#f0eee4'
 
     def __init__(
diff --git a/airflow/providers/google/cloud/transfers/salesforce_to_gcs.py b/airflow/providers/google/cloud/transfers/salesforce_to_gcs.py
index 3414ef6..3fb2251 100644
--- a/airflow/providers/google/cloud/transfers/salesforce_to_gcs.py
+++ b/airflow/providers/google/cloud/transfers/salesforce_to_gcs.py
@@ -68,7 +68,7 @@ class SalesforceToGcsOperator(BaseOperator):
         'bucket_name',
         'object_name',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
 
     def __init__(
         self,
diff --git a/airflow/providers/google/cloud/transfers/sql_to_gcs.py b/airflow/providers/google/cloud/transfers/sql_to_gcs.py
index e345f5e..8961e0e 100644
--- a/airflow/providers/google/cloud/transfers/sql_to_gcs.py
+++ b/airflow/providers/google/cloud/transfers/sql_to_gcs.py
@@ -100,7 +100,7 @@ class BaseSQLToGCSOperator(BaseOperator):
         'parameters',
         'impersonation_chain',
     )
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#a0e08c'
 
     def __init__(
diff --git a/airflow/providers/google/marketing_platform/operators/campaign_manager.py b/airflow/providers/google/marketing_platform/operators/campaign_manager.py
index 87276e6..89032f9 100644
--- a/airflow/providers/google/marketing_platform/operators/campaign_manager.py
+++ b/airflow/providers/google/marketing_platform/operators/campaign_manager.py
@@ -313,7 +313,7 @@ class GoogleCampaignManagerInsertReportOperator(BaseOperator):
         "impersonation_chain",
     )
 
-    template_ext = (".json",)
+    template_ext: Sequence[str] = (".json",)
 
     def __init__(
         self,
diff --git a/airflow/providers/google/marketing_platform/operators/display_video.py b/airflow/providers/google/marketing_platform/operators/display_video.py
index ce03a27..a7a1e7f 100644
--- a/airflow/providers/google/marketing_platform/operators/display_video.py
+++ b/airflow/providers/google/marketing_platform/operators/display_video.py
@@ -72,7 +72,7 @@ class GoogleDisplayVideo360CreateReportOperator(BaseOperator):
         "body",
         "impersonation_chain",
     )
-    template_ext = (".json",)
+    template_ext: Sequence[str] = (".json",)
 
     def __init__(
         self,
diff --git a/airflow/providers/google/marketing_platform/operators/search_ads.py b/airflow/providers/google/marketing_platform/operators/search_ads.py
index 88662f0..4afe23e 100644
--- a/airflow/providers/google/marketing_platform/operators/search_ads.py
+++ b/airflow/providers/google/marketing_platform/operators/search_ads.py
@@ -66,7 +66,7 @@ class GoogleSearchAdsInsertReportOperator(BaseOperator):
         "report",
         "impersonation_chain",
     )
-    template_ext = (".json",)
+    template_ext: Sequence[str] = (".json",)
 
     def __init__(
         self,
diff --git a/airflow/providers/google/suite/transfers/sql_to_sheets.py b/airflow/providers/google/suite/transfers/sql_to_sheets.py
index cf9206a..2a680a6 100644
--- a/airflow/providers/google/suite/transfers/sql_to_sheets.py
+++ b/airflow/providers/google/suite/transfers/sql_to_sheets.py
@@ -66,7 +66,7 @@ class SQLToGoogleSheetsOperator(BaseSQLOperator):
     )
 
     template_fields_renderers = {"sql": "sql"}
-    template_ext = (".sql",)
+    template_ext: Sequence[str] = (".sql",)
 
     ui_color = "#a0e08c"
 
diff --git a/airflow/providers/http/operators/http.py b/airflow/providers/http/operators/http.py
index abafb97..96f856d 100644
--- a/airflow/providers/http/operators/http.py
+++ b/airflow/providers/http/operators/http.py
@@ -74,7 +74,7 @@ class SimpleHttpOperator(BaseOperator):
         'headers',
     )
     template_fields_renderers = {'headers': 'json', 'data': 'py'}
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#f4a460'
 
     def __init__(
diff --git a/airflow/providers/jdbc/operators/jdbc.py b/airflow/providers/jdbc/operators/jdbc.py
index be90228..6881dde 100644
--- a/airflow/providers/jdbc/operators/jdbc.py
+++ b/airflow/providers/jdbc/operators/jdbc.py
@@ -48,7 +48,7 @@ class JdbcOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#ededed'
 
     def __init__(
diff --git a/airflow/providers/jenkins/operators/jenkins_job_trigger.py b/airflow/providers/jenkins/operators/jenkins_job_trigger.py
index f28bd56..90c121e 100644
--- a/airflow/providers/jenkins/operators/jenkins_job_trigger.py
+++ b/airflow/providers/jenkins/operators/jenkins_job_trigger.py
@@ -96,7 +96,7 @@ class JenkinsJobTriggerOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('parameters',)
-    template_ext = ('.json',)
+    template_ext: Sequence[str] = ('.json',)
     ui_color = '#f9ec86'
 
     def __init__(
diff --git a/airflow/providers/microsoft/azure/operators/adx.py b/airflow/providers/microsoft/azure/operators/adx.py
index 8dec651..89c038d 100644
--- a/airflow/providers/microsoft/azure/operators/adx.py
+++ b/airflow/providers/microsoft/azure/operators/adx.py
@@ -48,7 +48,7 @@ class AzureDataExplorerQueryOperator(BaseOperator):
 
     ui_color = '#00a1f2'
     template_fields: Sequence[str] = ('query', 'database')
-    template_ext = ('.kql',)
+    template_ext: Sequence[str] = ('.kql',)
 
     def __init__(
         self,
diff --git a/airflow/providers/microsoft/mssql/operators/mssql.py b/airflow/providers/microsoft/mssql/operators/mssql.py
index 4ecb7a5..e2df59c 100644
--- a/airflow/providers/microsoft/mssql/operators/mssql.py
+++ b/airflow/providers/microsoft/mssql/operators/mssql.py
@@ -54,7 +54,7 @@ class MsSqlOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#ededed'
 
     def __init__(
diff --git a/airflow/providers/mysql/operators/mysql.py b/airflow/providers/mysql/operators/mysql.py
index e7a2658..3fa7617 100644
--- a/airflow/providers/mysql/operators/mysql.py
+++ b/airflow/providers/mysql/operators/mysql.py
@@ -53,7 +53,7 @@ class MySqlOperator(BaseOperator):
 
     template_fields: Sequence[str] = ('sql', 'parameters')
     template_fields_renderers = {'sql': 'sql', 'parameters': 'json'}
-    template_ext = ('.sql', '.json')
+    template_ext: Sequence[str] = ('.sql', '.json')
     ui_color = '#ededed'
 
     def __init__(
diff --git a/airflow/providers/mysql/transfers/presto_to_mysql.py b/airflow/providers/mysql/transfers/presto_to_mysql.py
index b1bb5cf..57b8c43 100644
--- a/airflow/providers/mysql/transfers/presto_to_mysql.py
+++ b/airflow/providers/mysql/transfers/presto_to_mysql.py
@@ -48,7 +48,7 @@ class PrestoToMySqlOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql', 'mysql_table', 'mysql_preoperator')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     template_fields_renderers = {"sql": "sql", "mysql_preoperator": "sql"}
     ui_color = '#a0e08c'
 
diff --git a/airflow/providers/mysql/transfers/s3_to_mysql.py b/airflow/providers/mysql/transfers/s3_to_mysql.py
index f6971a8..344dd40 100644
--- a/airflow/providers/mysql/transfers/s3_to_mysql.py
+++ b/airflow/providers/mysql/transfers/s3_to_mysql.py
@@ -52,7 +52,7 @@ class S3ToMySqlOperator(BaseOperator):
         's3_source_key',
         'mysql_table',
     )
-    template_ext = ()
+    template_ext: Sequence[str] = ()
     ui_color = '#f4a460'
 
     def __init__(
diff --git a/airflow/providers/mysql/transfers/trino_to_mysql.py b/airflow/providers/mysql/transfers/trino_to_mysql.py
index 7d17382..081a316 100644
--- a/airflow/providers/mysql/transfers/trino_to_mysql.py
+++ b/airflow/providers/mysql/transfers/trino_to_mysql.py
@@ -48,7 +48,7 @@ class TrinoToMySqlOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql', 'mysql_table', 'mysql_preoperator')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     template_fields_renderers = {"sql": "sql", "mysql_preoperator": "sql"}
     ui_color = '#a0e08c'
 
diff --git a/airflow/providers/mysql/transfers/vertica_to_mysql.py b/airflow/providers/mysql/transfers/vertica_to_mysql.py
index 4e323f5..0c37d40 100644
--- a/airflow/providers/mysql/transfers/vertica_to_mysql.py
+++ b/airflow/providers/mysql/transfers/vertica_to_mysql.py
@@ -61,7 +61,7 @@ class VerticaToMySqlOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql', 'mysql_table', 'mysql_preoperator', 'mysql_postoperator')
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     template_fields_renderers = {
         "sql": "sql",
         "mysql_preoperator": "sql",
diff --git a/airflow/providers/oracle/operators/oracle.py b/airflow/providers/oracle/operators/oracle.py
index d97cf48..b78b9ee 100644
--- a/airflow/providers/oracle/operators/oracle.py
+++ b/airflow/providers/oracle/operators/oracle.py
@@ -44,7 +44,7 @@ class OracleOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#ededed'
 
     def __init__(
diff --git a/airflow/providers/postgres/operators/postgres.py b/airflow/providers/postgres/operators/postgres.py
index dd20de6..6bd0902 100644
--- a/airflow/providers/postgres/operators/postgres.py
+++ b/airflow/providers/postgres/operators/postgres.py
@@ -46,7 +46,7 @@ class PostgresOperator(BaseOperator):
 
     template_fields: Sequence[str] = ('sql',)
     template_fields_renderers = {'sql': 'sql'}
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#ededed'
 
     def __init__(
diff --git a/airflow/providers/qubole/sensors/qubole.py b/airflow/providers/qubole/sensors/qubole.py
index 0ea1c43..09ba321 100644
--- a/airflow/providers/qubole/sensors/qubole.py
+++ b/airflow/providers/qubole/sensors/qubole.py
@@ -33,7 +33,7 @@ class QuboleSensor(BaseSensorOperator):
 
     template_fields: Sequence[str] = ('data', 'qubole_conn_id')
 
-    template_ext = ('.txt',)
+    template_ext: Sequence[str] = ('.txt',)
 
     def __init__(self, *, data, qubole_conn_id: str = "qubole_default", **kwargs) -> None:
         self.data = data
diff --git a/airflow/providers/singularity/operators/singularity.py b/airflow/providers/singularity/operators/singularity.py
index e5c834c..2da8ec8 100644
--- a/airflow/providers/singularity/operators/singularity.py
+++ b/airflow/providers/singularity/operators/singularity.py
@@ -68,7 +68,7 @@ class SingularityOperator(BaseOperator):
         'command',
         'environment',
     )
-    template_ext = (
+    template_ext: Sequence[str] = (
         '.sh',
         '.bash',
     )
diff --git a/airflow/providers/snowflake/operators/snowflake.py b/airflow/providers/snowflake/operators/snowflake.py
index fbfa4da..3e3412e 100644
--- a/airflow/providers/snowflake/operators/snowflake.py
+++ b/airflow/providers/snowflake/operators/snowflake.py
@@ -86,7 +86,7 @@ class SnowflakeOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#ededed'
 
     def __init__(
@@ -199,7 +199,7 @@ class SnowflakeCheckOperator(SQLCheckOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#ededed'
 
     def __init__(
diff --git a/airflow/providers/snowflake/transfers/snowflake_to_slack.py b/airflow/providers/snowflake/transfers/snowflake_to_slack.py
index bb4042c..6fc181b 100644
--- a/airflow/providers/snowflake/transfers/snowflake_to_slack.py
+++ b/airflow/providers/snowflake/transfers/snowflake_to_slack.py
@@ -71,7 +71,7 @@ class SnowflakeToSlackOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql', 'slack_message')
-    template_ext = ['.sql', '.jinja', '.j2']
+    template_ext: Sequence[str] = ('.sql', '.jinja', '.j2')
     template_fields_renderers = {"slack_message": "jinja"}
     times_rendered = 0
 
diff --git a/airflow/providers/sqlite/operators/sqlite.py b/airflow/providers/sqlite/operators/sqlite.py
index 55a7f6a..691ad7f 100644
--- a/airflow/providers/sqlite/operators/sqlite.py
+++ b/airflow/providers/sqlite/operators/sqlite.py
@@ -41,7 +41,7 @@ class SqliteOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#cdaaed'
 
     def __init__(
diff --git a/airflow/providers/ssh/operators/ssh.py b/airflow/providers/ssh/operators/ssh.py
index 2c9aaf6..e30334b 100644
--- a/airflow/providers/ssh/operators/ssh.py
+++ b/airflow/providers/ssh/operators/ssh.py
@@ -68,7 +68,7 @@ class SSHOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('command', 'remote_host')
-    template_ext = ('.sh',)
+    template_ext: Sequence[str] = ('.sh',)
     template_fields_renderers = {"command": "bash"}
 
     def __init__(
diff --git a/airflow/providers/vertica/operators/vertica.py b/airflow/providers/vertica/operators/vertica.py
index 7fa4c53..a3ccf56 100644
--- a/airflow/providers/vertica/operators/vertica.py
+++ b/airflow/providers/vertica/operators/vertica.py
@@ -37,7 +37,7 @@ class VerticaOperator(BaseOperator):
     """
 
     template_fields: Sequence[str] = ('sql',)
-    template_ext = ('.sql',)
+    template_ext: Sequence[str] = ('.sql',)
     ui_color = '#b4e0ff'
 
     def __init__(
diff --git a/airflow/sensors/bash.py b/airflow/sensors/bash.py
index 22c3aa7..2bee043 100644
--- a/airflow/sensors/bash.py
+++ b/airflow/sensors/bash.py
@@ -19,6 +19,7 @@
 import os
 from subprocess import PIPE, STDOUT, Popen
 from tempfile import NamedTemporaryFile, TemporaryDirectory, gettempdir
+from typing import Sequence
 
 from airflow.sensors.base import BaseSensorOperator
 from airflow.utils.context import Context
@@ -42,7 +43,7 @@ class BashSensor(BaseSensorOperator):
     :type output_encoding: str
     """
 
-    template_fields = ('bash_command', 'env')
+    template_fields: Sequence[str] = ('bash_command', 'env')
 
     def __init__(self, *, bash_command, env=None, output_encoding='utf-8', **kwargs):
         super().__init__(**kwargs)
diff --git a/airflow/sensors/date_time.py b/airflow/sensors/date_time.py
index 2f9a5c5..34989d4 100644
--- a/airflow/sensors/date_time.py
+++ b/airflow/sensors/date_time.py
@@ -17,7 +17,7 @@
 # under the License.
 
 import datetime
-from typing import Union
+from typing import Sequence, Union
 
 from airflow.sensors.base import BaseSensorOperator
 from airflow.triggers.temporal import DateTimeTrigger
@@ -55,7 +55,7 @@ class DateTimeSensor(BaseSensorOperator):
     :type target_time: str or datetime.datetime
     """
 
-    template_fields = ("target_time",)
+    template_fields: Sequence[str] = ("target_time",)
 
     def __init__(self, *, target_time: Union[str, datetime.datetime], **kwargs) -> None:
         super().__init__(**kwargs)
diff --git a/airflow/sensors/filesystem.py b/airflow/sensors/filesystem.py
index c6df748..e299bdb 100644
--- a/airflow/sensors/filesystem.py
+++ b/airflow/sensors/filesystem.py
@@ -20,6 +20,7 @@
 import datetime
 import os
 from glob import glob
+from typing import Sequence
 
 from airflow.hooks.filesystem import FSHook
 from airflow.sensors.base import BaseSensorOperator
@@ -44,7 +45,7 @@ class FileSensor(BaseSensorOperator):
     :type recursive: bool
     """
 
-    template_fields = ('filepath',)
+    template_fields: Sequence[str] = ('filepath',)
     ui_color = '#91818a'
 
     def __init__(self, *, filepath, fs_conn_id='fs_default', recursive=False, **kwargs):
diff --git a/airflow/sensors/python.py b/airflow/sensors/python.py
index f770965..7e5d6f3 100644
--- a/airflow/sensors/python.py
+++ b/airflow/sensors/python.py
@@ -15,7 +15,7 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-from typing import Any, Callable, Dict, List, Mapping, Optional
+from typing import Any, Callable, Dict, List, Mapping, Optional, Sequence
 
 from airflow.sensors.base import BaseSensorOperator
 from airflow.utils.context import Context
@@ -46,7 +46,7 @@ class PythonSensor(BaseSensorOperator):
     :type templates_dict: dict of str
     """
 
-    template_fields = ('templates_dict', 'op_args', 'op_kwargs')
+    template_fields: Sequence[str] = ('templates_dict', 'op_args', 'op_kwargs')
 
     def __init__(
         self,
diff --git a/docs/apache-airflow/concepts/operators.rst b/docs/apache-airflow/concepts/operators.rst
index c66c2eb..83ca1e4 100644
--- a/docs/apache-airflow/concepts/operators.rst
+++ b/docs/apache-airflow/concepts/operators.rst
@@ -88,7 +88,7 @@ You can also use Jinja templating with nested fields, as long as these nested fi
 .. code-block:: python
 
     class MyDataReader:
-        template_fields = ["path"]
+        template_fields: Sequence[str] = ("path",)
 
         def __init__(self, my_path):
             self.path = my_path
@@ -110,7 +110,7 @@ Deep nested fields can also be substituted, as long as all intermediate fields a
 .. code-block:: python
 
     class MyDataTransformer:
-        template_fields = ["reader"]
+        template_fields: Sequence[str] = ("reader",)
 
         def __init__(self, my_reader):
             self.reader = my_reader
@@ -119,7 +119,7 @@ Deep nested fields can also be substituted, as long as all intermediate fields a
 
 
     class MyDataReader:
-        template_fields = ["path"]
+        template_fields: Sequence[str] = ("path",)
 
         def __init__(self, my_path):
             self.path = my_path
diff --git a/docs/apache-airflow/howto/custom-operator.rst b/docs/apache-airflow/howto/custom-operator.rst
index 46431d1..a103210 100644
--- a/docs/apache-airflow/howto/custom-operator.rst
+++ b/docs/apache-airflow/howto/custom-operator.rst
@@ -153,7 +153,7 @@ the operator.
 
         class HelloOperator(BaseOperator):
 
-            template_fields = ["name"]
+            template_fields: Sequence[str] = ("name",)
 
             def __init__(self, name: str, **kwargs) -> None:
                 super().__init__(**kwargs)
@@ -186,8 +186,8 @@ with actual value. Note that Jinja substitutes the operator attributes and not t
 
         class HelloOperator(BaseOperator):
 
-            template_fields = ["guest_name"]
-            template_ext = [".sql"]
+            template_fields: Sequence[str] = ("guest_name",)
+            template_ext = ".sql"
 
             def __init__(self, name: str, **kwargs) -> None:
                 super().__init__(**kwargs)
@@ -201,7 +201,7 @@ from template field renders in Web UI. For example:
 .. code-block:: python
 
         class MyRequestOperator(BaseOperator):
-            template_fields = ["request_body"]
+            template_fields: Sequence[str] = ("request_body",)
             template_fields_renderers = {"request_body": "json"}
 
             def __init__(self, request_body: str, **kwargs) -> None:
@@ -214,7 +214,7 @@ dot-separated key path to extract and render individual elements appropriately.
 .. code-block:: python
 
         class MyConfigOperator(BaseOperator):
-            template_fields = ["configuration"]
+            template_fields: Sequence[str] = ("configuration",)
             template_fields_renderers = {
                 "configuration": "json",
                 "configuration.query.sql": "sql",
diff --git a/tests/dags/test_only_dummy_tasks.py b/tests/dags/test_only_dummy_tasks.py
index dac9fa4..00256f3 100644
--- a/tests/dags/test_only_dummy_tasks.py
+++ b/tests/dags/test_only_dummy_tasks.py
@@ -16,6 +16,7 @@
 # specific language governing permissions and limitations
 # under the License.
 from datetime import datetime
+from typing import Sequence
 
 from airflow.models import DAG
 from airflow.operators.dummy import DummyOperator
@@ -32,7 +33,7 @@ dag = DAG(dag_id="test_only_dummy_tasks", default_args=default_args, schedule_in
 
 class MyDummyOperator(DummyOperator):
     template_fields_renderers = {"body": "json"}
-    template_fields = ("body",)
+    template_fields: Sequence[str] = ("body",)
 
     def __init__(self, body, *args, **kwargs):
         super().__init__(*args, **kwargs)
diff --git a/tests/models/test_dag.py b/tests/models/test_dag.py
index 044ba9d..4fd529e 100644
--- a/tests/models/test_dag.py
+++ b/tests/models/test_dag.py
@@ -27,7 +27,7 @@ from contextlib import redirect_stdout
 from datetime import timedelta
 from pathlib import Path
 from tempfile import NamedTemporaryFile
-from typing import List, Optional
+from typing import List, Optional, Sequence
 from unittest import mock
 from unittest.mock import patch
 
@@ -548,7 +548,7 @@ class TestDag(unittest.TestCase):
                 task = DummyOperator(task_id='op1')
 
             task.test_field = template_file
-            task.template_fields = ('test_field',)
+            task.template_fields: Sequence[str] = ('test_field',)
             task.template_ext = ('.template',)
             task.resolve_template_files()
 
@@ -566,7 +566,7 @@ class TestDag(unittest.TestCase):
                 task = DummyOperator(task_id='op1')
 
             task.test_field = [template_file, 'some_string']
-            task.template_fields = ('test_field',)
+            task.template_fields: Sequence[str] = ('test_field',)
             task.template_ext = ('.template',)
             task.resolve_template_files()
 
diff --git a/tests/providers/slack/operators/test_slack_webhook.py b/tests/providers/slack/operators/test_slack_webhook.py
index f9cc835..cfb45ba 100644
--- a/tests/providers/slack/operators/test_slack_webhook.py
+++ b/tests/providers/slack/operators/test_slack_webhook.py
@@ -18,6 +18,7 @@
 #
 
 import unittest
+from typing import Sequence
 
 from airflow.models.dag import DAG
 from airflow.providers.slack.operators.slack_webhook import SlackWebhookOperator
@@ -64,7 +65,7 @@ class TestSlackWebhookOperator(unittest.TestCase):
     def test_assert_templated_fields(self):
         operator = SlackWebhookOperator(task_id='slack_webhook_job', dag=self.dag, **self._config)
 
-        template_fields = (
+        template_fields: Sequence[str] = (
             'webhook_token',
             'message',
             'attachments',
diff --git a/tests/test_utils/mock_operators.py b/tests/test_utils/mock_operators.py
index 9c30c8a..aa6a4fd 100644
--- a/tests/test_utils/mock_operators.py
+++ b/tests/test_utils/mock_operators.py
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 import warnings
-from typing import NamedTuple
+from typing import NamedTuple, Sequence
 from unittest import mock
 
 import attr
@@ -35,7 +35,7 @@ class MockNamedTuple(NamedTuple):
 class MockOperator(BaseOperator):
     """Operator for testing purposes."""
 
-    template_fields = ("arg1", "arg2")
+    template_fields: Sequence[str] = ("arg1", "arg2")
 
     def __init__(self, arg1: str = "", arg2: str = "", **kwargs):
         super().__init__(**kwargs)