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

jrmccluskey pushed a commit to branch ruffExperiment
in repository https://gitbox.apache.org/repos/asf/beam.git

commit ebb71f09d9b6dadff17f441ac8120e5957717b1f
Author: jrmccluskey <[email protected]>
AuthorDate: Thu Mar 26 11:16:11 2026 -0400

    Swap out pylint and flake8 with ruff
---
 .../python/apache_beam/typehints/typehints_test.py |  3 +-
 sdks/python/ruff.toml                              | 96 ++++++++++++++++++++++
 sdks/python/scripts/run_pylint.sh                  |  7 +-
 sdks/python/tox.ini                                |  7 +-
 4 files changed, 102 insertions(+), 11 deletions(-)

diff --git a/sdks/python/apache_beam/typehints/typehints_test.py 
b/sdks/python/apache_beam/typehints/typehints_test.py
index 1377bea6d56..992c129fd8a 100644
--- a/sdks/python/apache_beam/typehints/typehints_test.py
+++ b/sdks/python/apache_beam/typehints/typehints_test.py
@@ -712,7 +712,8 @@ class DictHintTestCase(TypeHintTestCase):
 
   def test_type_check_collection(self):
     hint = typehints.Dict[str, int]
-    l = collections.defaultdict(list[("blue", 2)])
+    element = ("blue", 2)
+    l = collections.defaultdict(list[element])
     self.assertIsNone(hint.type_check(l))
 
   def test_type_check_invalid_key_type(self):
diff --git a/sdks/python/ruff.toml b/sdks/python/ruff.toml
new file mode 100644
index 00000000000..5a862e013f1
--- /dev/null
+++ b/sdks/python/ruff.toml
@@ -0,0 +1,96 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+exclude = [
+    ".bzr",
+    ".direnv",
+    ".eggs",
+    ".git",
+    ".git-rewrite",
+    ".hg",
+    ".ipynb_checkpoints",
+    ".mypy_cache",
+    ".nox",
+    ".pants.d",
+    ".pyenv",
+    ".pytest_cache",
+    ".pytype",
+    ".ruff_cache",
+    ".svn",
+    ".tox",
+    ".venv",
+    ".vscode",
+    "__pypackages__",
+    "_build",
+    "buck-out",
+    "build",
+    "dist",
+    "node_modules",
+    "site-packages",
+    "venv",
+    "*.pxd",
+    "*.pyx",
+    "*pb2*.py",
+    "**/examples/**/*.py",
+    "**/examples/**/*.ipynb",
+    "**/portability/api/**/*.py",
+    "**/portability/api/__init__.py",
+]
+
+target-version = "py310"
+
+src = ["apache_beam"]
+
+[lint]
+select = ["E9", "PL", "F821", "F822", "F823"]
+ignore = [
+    # Ignored Pylint Checks
+    "PLC0415",  # import-outside-toplevel
+    "PLR2004",  # magic-value-comparison
+    "PLR0913",  # too-many-arguments
+    "PLR0912",  # too-many-branches
+    "PLW0108",  # unnecessary-lambda
+    "PLW2901",  # redefined-loop-name
+    "PLR0915",  # too-many-statements
+    "PLR1714",  # repeated-equality-comparison
+    "PLR0911",  # too-many-return-statements
+    "PLR5501",  # collapsible-else-if
+    "PLW0603",  # global-statement
+    "PLR1730",  # if-stmt-min-max
+    "PLW1641",  # eq-without-hash
+    "PLW0602",  # global-variable-not-assigned
+    "PLC1802",  # len-test
+    "PLC3002",  # unnecessary-direct-lambda-call
+    "PLW0642",  # self-or-cls-assignment
+    "PLR1733",  # unnecessary-dict-index-lookup
+    "PLR0402",  # manual-from-import
+    "PLC0132",  # type-param-name-mismatch
+    "PLC0206",  # dict-index-missing-items
+    "PLC0207",  # missing-maxsplit-arg
+    "PLR1704",  # redefined-argument-from-local
+    "PLR1711",  # useless-return
+    "PLW0406",  # import-self
+    "PLW3301",  # nested-min-max
+    "PLR2044",  # empty-comment
+]
+
+# Allow fix for all enabled rules (when `--fix`) is provided.
+fixable = ["ALL"]
+unfixable = []
+
+# Allow unused variables when underscore-prefixed.
+dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
\ No newline at end of file
diff --git a/sdks/python/scripts/run_pylint.sh 
b/sdks/python/scripts/run_pylint.sh
index 4a6bf4c2ef0..a9a0b0ec50d 100755
--- a/sdks/python/scripts/run_pylint.sh
+++ b/sdks/python/scripts/run_pylint.sh
@@ -78,11 +78,8 @@ done
 echo -e "Skipping lint for files:\n${FILES_TO_IGNORE}"
 echo -e "Linting modules:\n${MODULE}"
 
-echo "Running pylint..."
-pylint -j8 ${MODULE} --ignore-patterns="$FILES_TO_IGNORE"
-echo "Running flake8..."
-flake8 ${MODULE} --count --select=E9,F821,F822,F823 --show-source --statistics 
\
-  --exclude="${FILES_TO_IGNORE}"
+echo "Running ruff..."
+ruff check ${MODULE} --extend-exclude="$FILES_TO_IGNORE"
 
 echo "Running isort..."
 # Skip files where isort is behaving weirdly
diff --git a/sdks/python/tox.ini b/sdks/python/tox.ini
index cb84425a35a..a2b7195025a 100644
--- a/sdks/python/tox.ini
+++ b/sdks/python/tox.ini
@@ -182,13 +182,10 @@ commands =
 setenv =
 # keep the version of pylint in sync with the 'rev' in .pre-commit-config.yaml
 deps =
-  astroid<4.1.0,>=4.0.1
-  pycodestyle==2.8.0
-  pylint==4.0.2
+  ruff==0.15.7
   isort==7.0.0
-  flake8==4.0.1
 commands =
-  pylint --version
+  ruff --version
   time {toxinidir}/scripts/run_pylint.sh
 
 [testenv:whitespacelint]

Reply via email to