Skip to content

Commit 669b026

Browse files
BasPHpotiuk
authored andcommitted
[AIRFLOW-4364] Add Pylint to CI (apache#5238)
1 parent 6f684d0 commit 669b026

24 files changed

+1666
-17
lines changed

.pylintrc

+594
Large diffs are not rendered by default.

.rat-excludes

+3
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,6 @@ apache-airflow-.*\+bin.tar.gz.*
6767

6868
# vendored modules
6969
_vendor/*
70+
71+
# Temporary list of files to make compatible with Pylint
72+
pylint_todo.txt

.travis.yml

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ jobs:
5757
stage: pre-test
5858
install: pip install -e .[doc]
5959
script: docs/build.sh
60+
- name: Pylint
61+
stage: pre-test
62+
install: pip install pylint~=2.3.1 # Ensure the same version as in setup.py
63+
script: scripts/ci/ci_pylint.sh
64+
cache: false
6065
cache:
6166
directories:
6267
- $HOME/.wheelhouse/

CONTRIBUTING.md

+1
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ meets these guidelines:
275275
1. If the pull request adds functionality, the docs should be updated as part of the same PR. Doc string are often sufficient. Make sure to follow the Sphinx compatible standards.
276276
1. The pull request should work for Python 2.7 and 3.5. If you need help writing code that works in both Python 2 and 3, see the documentation at the [Python-Future project](http://python-future.org) (the future package is an Airflow requirement and should be used where possible).
277277
1. As Airflow grows as a project, we try to enforce a more consistent style and try to follow the Python community guidelines. We currently enforce most [PEP8](https://www.python.org/dev/peps/pep-0008/) and a few other linting rules. It is usually a good idea to lint locally as well using [flake8](https://flake8.readthedocs.org/en/latest/) using `flake8 airflow tests`. `git diff upstream/master -u -- "*.py" | flake8 --diff` will return any changed files in your branch that require linting.
278+
1. We also apply [Pylint](https://www.pylint.org) for linting (static code analysis). Run locally with `./scripts/ci/ci_pylint.sh`.
278279
1. Please read this excellent [article](http://chris.beams.io/posts/git-commit/) on commit messages and adhere to them. It makes the lives of those who come after you a lot easier.
279280

280281
### Testing on Travis CI

airflow/contrib/example_dags/example_azure_cosmosdb_sensor.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,4 @@
6161
document={"id": "someuniqueid", "param1": "value1", "param2": "value2"},
6262
azure_cosmos_conn_id='azure_cosmos_default')
6363

64-
t1 >> t2
64+
t1 >> t2 # pylint: disable=pointless-statement

airflow/contrib/example_dags/example_dingding_operator.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,12 @@ def failure_callback(context):
212212
dag=dag,
213213
)
214214

215-
[
215+
[ # pylint: disable=pointless-statement
216216
text_msg_remind_none,
217217
text_msg_remind_specific,
218218
text_msg_remind_include_invalid,
219219
text_msg_remind_all
220-
] >> link_msg >> markdown_msg >> [
220+
] >> link_msg >> markdown_msg >> [ # pylint: disable=pointless-statement
221221
single_action_card_msg,
222222
multi_action_card_msg
223-
] >> feed_card_msg >> msg_failure_callback
223+
] >> feed_card_msg >> msg_failure_callback # pylint: disable=pointless-statement

airflow/contrib/example_dags/example_gcp_bigtable_operators.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
* CBT_POKE_INTERVAL - number of seconds between every attempt of Sensor check
4747
4848
"""
49+
4950
import json
5051

5152
from os import getenv
@@ -108,7 +109,7 @@
108109
cluster_storage_type=int(CBT_CLUSTER_STORAGE_TYPE),
109110
task_id='create_instance_task2',
110111
)
111-
create_instance_task >> create_instance_task2
112+
create_instance_task >> create_instance_task2 # pylint: disable=pointless-statement
112113
# [END howto_operator_gcp_bigtable_instance_create]
113114

114115
# [START howto_operator_gcp_bigtable_cluster_update]
@@ -125,7 +126,7 @@
125126
nodes=int(CBT_CLUSTER_NODES_UPDATED),
126127
task_id='update_cluster_task2',
127128
)
128-
cluster_update_task >> cluster_update_task2
129+
cluster_update_task >> cluster_update_task2 # pylint: disable=pointless-statement
129130
# [END howto_operator_gcp_bigtable_cluster_update]
130131

131132
# [START howto_operator_gcp_bigtable_instance_delete]
@@ -152,7 +153,7 @@
152153
table_id=CBT_TABLE_ID,
153154
task_id='create_table_task2',
154155
)
155-
create_table_task >> create_table_task2
156+
create_table_task >> create_table_task2 # pylint: disable=pointless-statement
156157
# [END howto_operator_gcp_bigtable_table_create]
157158

158159
# [START howto_operator_gcp_bigtable_table_wait_for_replication]
@@ -187,6 +188,7 @@
187188
)
188189
# [END howto_operator_gcp_bigtable_table_delete]
189190

191+
# pylint: disable=pointless-statement
190192
wait_for_table_replication_task >> delete_table_task
191193
wait_for_table_replication_task2 >> delete_table_task
192194
wait_for_table_replication_task >> delete_table_task2
@@ -203,3 +205,4 @@
203205
# Only delete instances after all tables are deleted
204206
[delete_table_task, delete_table_task2] >> \
205207
delete_instance_task >> delete_instance_task2
208+
# pylint: enable=pointless-statement

airflow/contrib/example_dags/example_gcp_compute.py

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* GCE_SHORT_MACHINE_TYPE_NAME - Machine type resource name to set, e.g. 'n1-standard-1'.
3030
See https://cloud.google.com/compute/docs/machine-types
3131
"""
32+
3233
import os
3334

3435
import airflow
@@ -110,5 +111,7 @@
110111
)
111112
# [END howto_operator_gce_set_machine_type_no_project_id]
112113

114+
# pylint: disable=pointless-statement
113115
gce_instance_start >> gce_instance_start2 >> gce_instance_stop >> \
114116
gce_instance_stop2 >> gce_set_machine_type >> gce_set_machine_type2
117+
# pylint: enable=pointless-statement

airflow/contrib/example_dags/example_gcp_compute_igm.py

+3
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@
139139
task_id='gcp_compute_igm_group_manager_update_template_2'
140140
)
141141
# [END howto_operator_gce_igm_update_template_no_project_id]
142+
143+
# pylint: disable=pointless-statement
142144
gce_instance_template_copy >> gce_instance_template_copy2 >> \
143145
gce_instance_group_manager_update_template >> \
144146
gce_instance_group_manager_update_template2
147+
# pylint: enable=pointless-statement

airflow/contrib/example_dags/example_gcp_function.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,4 @@
130130
name=FUNCTION_NAME
131131
)
132132
# [END howto_operator_gcf_delete]
133-
deploy_task >> deploy2_task >> delete_task
133+
deploy_task >> deploy2_task >> delete_task # pylint: disable=pointless-statement

airflow/contrib/example_dags/example_gcp_natural_language.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
Example Airflow DAG for Google Cloud Natural Language service
2222
"""
2323

24-
2524
from google.cloud.language_v1.proto.language_service_pb2 import Document
2625

2726
import airflow
@@ -108,7 +107,9 @@
108107
)
109108
# [END howto_operator_gcp_natural_language_analyze_classify_text_result]
110109

110+
# pylint: disable=pointless-statement
111111
analyze_entities >> analyze_entities_result
112112
analyze_entity_sentiment >> analyze_entity_sentiment_result
113113
analyze_sentiment >> analyze_sentiment_result
114114
analyze_classify_text >> analyze_classify_text_result
115+
# pylint: enable=pointless-statement

airflow/contrib/example_dags/example_gcp_spanner.py

+2
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@
183183
)
184184
# [END howto_operator_spanner_delete]
185185

186+
# pylint: disable=pointless-statement
186187
spanner_instance_create_task \
187188
>> spanner_instance_update_task \
188189
>> spanner_database_deploy_task \
@@ -196,3 +197,4 @@
196197
>> spanner_database_delete_task2 \
197198
>> spanner_instance_delete_task \
198199
>> spanner_instance_delete_task2
200+
# pylint: enable=pointless-statement

airflow/contrib/example_dags/example_gcp_speech.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
)
8585
# [END howto_operator_speech_to_text_recognize]
8686

87-
text_to_speech_synthesize_task >> speech_to_text_recognize_task
87+
text_to_speech_synthesize_task >> speech_to_text_recognize_task # pylint: disable=pointless-statement
8888

8989
# [START howto_operator_translate_speech]
9090
translate_speech_task = GcpTranslateSpeechOperator(
@@ -99,4 +99,4 @@
9999
)
100100
# [END howto_operator_translate_speech]
101101

102-
text_to_speech_synthesize_task >> translate_speech_task
102+
text_to_speech_synthesize_task >> translate_speech_task # pylint: disable=pointless-statement

airflow/contrib/example_dags/example_gcp_sql.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
) as dag:
187187

188188
def next_dep(task, prev):
189-
prev >> task
189+
prev >> task # pylint: disable=pointless-statement
190190
return task
191191

192192
# ############################################## #

airflow/contrib/example_dags/example_gcp_sql_query.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ def get_absolute_path(path):
287287
)
288288
tasks.append(task)
289289
if prev_task:
290-
prev_task >> task
290+
prev_task >> task # pylint: disable=pointless-statement
291291
prev_task = task
292292

293293
# [END howto_operator_cloudsql_query_operators]

airflow/contrib/example_dags/example_gcp_transfer.py

+3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
Look at documentation of :class:`~airflow.operators.sensors.BaseSensorOperator` for more information
3939
4040
"""
41+
4142
import os
4243
from datetime import datetime, timedelta
4344
from typing import Any, Dict
@@ -247,7 +248,9 @@
247248
project_id=GCP_PROJECT_ID,
248249
)
249250

251+
# pylint: disable=pointless-statement
250252
create_transfer_job_from_aws >> wait_for_operation_to_start >> pause_operation >> \
251253
list_operations >> get_operation >> resume_operation >> wait_for_operation_to_end >> \
252254
create_transfer_job_from_gcp >> wait_for_second_operation_to_start >> cancel_operation >> \
253255
delete_transfer_from_aws_job >> delete_transfer_from_gcp_job
256+
# pylint: enable=pointless-statement

airflow/contrib/example_dags/example_gcp_translate.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
service in the Google Cloud Platform.
2323
2424
"""
25+
2526
import airflow
2627
from airflow import models
2728

@@ -48,5 +49,5 @@
4849
task_id='access',
4950
bash_command="echo '{{ task_instance.xcom_pull(\"translate\")[0] }}'"
5051
)
51-
product_set_create >> translation_access
52+
product_set_create >> translation_access # pylint: disable=pointless-statement
5253
# [END howto_operator_translate_access]

airflow/contrib/example_dags/example_gcp_vision.py

+7
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* GCP_VISION_ANNOTATE_IMAGE_URL - A link to the bucket that contains the file to be annotated.
3232
3333
"""
34+
3435
import os
3536

3637
# [START howto_operator_vision_retry_import]
@@ -229,6 +230,7 @@
229230
)
230231
# [END howto_operator_vision_remove_product_from_product_set]
231232

233+
# pylint: disable=pointless-statement
232234
# Product path
233235
product_create >> product_get >> product_update >> product_delete
234236

@@ -244,6 +246,7 @@
244246
add_product_to_product_set >> remove_product_from_product_set
245247
remove_product_from_product_set >> product_delete
246248
remove_product_from_product_set >> product_set_delete
249+
# pylint: enable=pointless-statement
247250

248251
with models.DAG(
249252
'example_gcp_vision_explicit_id', default_args=default_args, schedule_interval=None
@@ -381,6 +384,7 @@
381384
)
382385
# [END howto_operator_vision_remove_product_from_product_set_2]
383386

387+
# pylint: disable=pointless-statement
384388
# Product path
385389
product_create_2 >> product_create_2_idempotence >> product_get_2 >> product_update_2 >> product_delete_2
386390

@@ -397,6 +401,7 @@
397401
product_create_2 >> add_product_to_product_set_2
398402
remove_product_from_product_set_2 >> product_set_delete_2
399403
remove_product_from_product_set_2 >> product_delete_2
404+
# pylint: enable=pointless-statement
400405

401406
with models.DAG(
402407
'example_gcp_vision_annotate_image', default_args=default_args, schedule_interval=None
@@ -476,9 +481,11 @@
476481
)
477482
# [END howto_operator_vision_detect_safe_search_result]
478483

484+
# pylint: disable=pointless-statement
479485
annotate_image >> annotate_image_result
480486

481487
detect_text >> detect_text_result
482488
document_detect_text >> document_detect_text_result
483489
detect_labels >> detect_labels_result
484490
detect_safe_search >> detect_safe_search_result
491+
# pylint: enable=pointless-statement

airflow/contrib/example_dags/example_gcs_acl.py

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* GCS_ACL_BUCKET_ROLE - The access permission for the entity for the bucket.
3131
* GCS_ACL_OBJECT_ROLE - The access permission for the entity for the object.
3232
"""
33+
3334
import os
3435

3536
import airflow
@@ -73,4 +74,5 @@
7374
)
7475
# [END howto_operator_gcs_object_create_acl_entry_task]
7576

77+
# pylint: disable=pointless-statement
7678
gcs_bucket_create_acl_entry_task >> gcs_object_create_acl_entry_task

airflow/contrib/example_dags/example_gcs_to_bq_operator.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,4 @@
6464
bash_command='bq rm -rf airflow_test',
6565
dag=dag)
6666

67-
create_test_dataset >> load_csv >> delete_test_dataset
67+
create_test_dataset >> load_csv >> delete_test_dataset # pylint: disable=pointless-statement

airflow/contrib/example_dags/example_pubsub_flow.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,5 @@
8282
t6 = PubSubSubscriptionDeleteOperator(task_id='delete-subscription')
8383
t7 = PubSubTopicDeleteOperator(task_id='delete-topic')
8484

85-
t1 >> t2 >> t3
86-
t2 >> t4 >> t5 >> t6 >> t7
85+
t1 >> t2 >> t3 # pylint: disable=pointless-statement
86+
t2 >> t4 >> t5 >> t6 >> t7 # pylint: disable=pointless-statement

scripts/ci/ci_pylint.sh

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env bash
2+
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one or more
5+
# contributor license agreements. See the NOTICE file distributed with
6+
# this work for additional information regarding copyright ownership.
7+
# The ASF licenses this file to You under the Apache License, Version 2.0
8+
# (the "License"); you may not use this file except in compliance with
9+
# the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
#
19+
20+
# Script to run Pylint on all code. Should be started from root directory:
21+
# ./[airflow dir]/scripts/ci/ci_pylint.sh
22+
23+
set -ex
24+
25+
find . -name "*.py" \
26+
-not -path "./.eggs/*" \
27+
-not -path "./airflow/www/node_modules/*" \
28+
-not -path "./airflow/_vendor/*" \
29+
-not -path "./build" | grep -vFf scripts/ci/pylint_todo.txt | xargs pylint --output-format=colorized

0 commit comments

Comments
 (0)