Merge branch 'main' into bchinn-pre-commit
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 5889823..787a711 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -13,11 +13,6 @@
 # limitations under the License.
 
 ---
-buildifier:
-  # keep these arguments in sync with .pre-commit-config.yaml
-  # Use a specific version to avoid skew issues when new versions are released.
-  version: 6.1.0
-  warnings: "all"
 # NOTE: Minimum supported version is 7.x
 .minimum_supported_version: &minimum_supported_version
   # For testing minimum supported version.
diff --git a/.bazelrc b/.bazelrc
index d7e1771..1129b62 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -4,8 +4,8 @@
 # (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
 # To update these lines, execute
 # `bazel run @rules_bazel_integration_test//tools:update_deleted_packages`
-build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,rules_python-repro,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data,tests/whl_with_build_files/testdata,tests/whl_with_build_files/testdata/somepkg,tests/whl_with_build_files/testdata/somepkg-1.0.dist-info,tests/whl_with_build_files/testdata/somepkg/subpkg
-query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,rules_python-repro,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data,tests/whl_with_build_files/testdata,tests/whl_with_build_files/testdata/somepkg,tests/whl_with_build_files/testdata/somepkg-1.0.dist-info,tests/whl_with_build_files/testdata/somepkg/subpkg
+build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/python/private,gazelle/pythonconfig,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data,tests/whl_with_build_files/testdata,tests/whl_with_build_files/testdata/somepkg,tests/whl_with_build_files/testdata/somepkg-1.0.dist-info,tests/whl_with_build_files/testdata/somepkg/subpkg
+query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/python/private,gazelle/pythonconfig,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data,tests/whl_with_build_files/testdata,tests/whl_with_build_files/testdata/somepkg,tests/whl_with_build_files/testdata/somepkg-1.0.dist-info,tests/whl_with_build_files/testdata/somepkg/subpkg
 
 test --test_output=errors
 
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
new file mode 100644
index 0000000..7827bdc
--- /dev/null
+++ b/.github/workflows/lint.yaml
@@ -0,0 +1,22 @@
+name: lint
+
+on:
+  push:
+    branches:
+      - main
+  pull_request:
+    types:
+      - opened
+      - synchronize
+
+defaults:
+  run:
+    shell: bash
+
+jobs:
+  ci:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v3
+      - uses: pre-commit/action@v3.0.1
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 67a02fc..4fe3fa5 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -25,18 +25,15 @@
     hooks:
       - id: buildifier
         args: &args
-          # Keep this argument in sync with .bazelci/presubmit.yaml
           - --warnings=all
       - id: buildifier-lint
         args: *args
   - repo: https://github.com/pycqa/isort
-    rev: 5.12.0
+    rev: 6.0.1
     hooks:
       - id: isort
         name: isort (python)
-        args:
-          - --profile
-          - black
+        args: ["--profile", "black", "--filter-files"]
   - repo: https://github.com/psf/black
     rev: 25.1.0
     hooks:
diff --git a/docs/conf.py b/docs/conf.py
index 8537d99..e424885 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -141,7 +141,10 @@
 
 # --- Extlinks configuration
 extlinks = {
-    "gh-issue": (f"https://github.com/bazel-contrib/rules_python/issues/%s", "#%s issue"),
+    "gh-issue": (
+        f"https://github.com/bazel-contrib/rules_python/issues/%s",
+        "#%s issue",
+    ),
     "gh-path": (f"https://github.com/bazel-contrib/rules_python/tree/main/%s", "%s"),
     "gh-pr": (f"https://github.com/bazel-contrib/rules_python/pulls/%s", "#%s PR"),
 }
diff --git a/examples/wheel/wheel_test.py b/examples/wheel/wheel_test.py
index 7f19ecd..09a41cd 100644
--- a/examples/wheel/wheel_test.py
+++ b/examples/wheel/wheel_test.py
@@ -566,7 +566,9 @@
             )
 
     def test_requires_dist_depends_on_extras(self):
-        filename = self._get_path("requires_dist_depends_on_extras-0.0.1-py3-none-any.whl")
+        filename = self._get_path(
+            "requires_dist_depends_on_extras-0.0.1-py3-none-any.whl"
+        )
 
         with zipfile.ZipFile(filename) as zf:
             self.assertAllEntriesHasReproducibleMetadata(zf)
@@ -591,7 +593,9 @@
             )
 
     def test_requires_dist_depends_on_extras_file(self):
-        filename = self._get_path("requires_dist_depends_on_extras_using_file-0.0.1-py3-none-any.whl")
+        filename = self._get_path(
+            "requires_dist_depends_on_extras_using_file-0.0.1-py3-none-any.whl"
+        )
 
         with zipfile.ZipFile(filename) as zf:
             self.assertAllEntriesHasReproducibleMetadata(zf)
diff --git a/gazelle/python/testdata/dependency_resolution_order/__init__.py b/gazelle/python/testdata/dependency_resolution_order/__init__.py
index 4b40aa9..8149451 100644
--- a/gazelle/python/testdata/dependency_resolution_order/__init__.py
+++ b/gazelle/python/testdata/dependency_resolution_order/__init__.py
@@ -17,12 +17,11 @@
 import bar
 import baz
 import foo
+import third_party
 
 # Ensure that even though @gazelle_python_test//other_pip_dep provides "third_party",
 # we can still override "third_party.foo.bar"
 import third_party.foo.bar
-
-import third_party
 from third_party import baz
 
 _ = sys
diff --git a/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/__init__.py b/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/__init__.py
index 02feaeb..44cf2f9 100644
--- a/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/__init__.py
+++ b/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/__init__.py
@@ -1,3 +1,2 @@
-
 def some_init():
     return "some_init"
diff --git a/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/some_module.py b/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/some_module.py
index 3cae706..aaa161c 100644
--- a/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/some_module.py
+++ b/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/some_module.py
@@ -1,3 +1,2 @@
-
 def some_function():
     return "some_function"
diff --git a/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/subpackage2/script.py b/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/subpackage2/script.py
index e93f077..aa62cb2 100644
--- a/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/subpackage2/script.py
+++ b/gazelle/python/testdata/relative_imports_package_mode/package1/subpackage1/subpackage2/script.py
@@ -1,11 +1,11 @@
-from ...my_library import (
+from ...my_library import (  # Import path should be package1.my_library.some_function
     some_function,
-)  # Import path should be package1.my_library.some_function
-from ...my_library.foo import (
+)
+from ...my_library.foo import (  # Import path should be package1.my_library.foo.some_function
     some_function,
-)  # Import path should be package1.my_library.foo.some_function
-from .library import (
-    other_module,
-)  # Import path should be package1.subpackage1.subpackage2.library.other_module
-from .. import some_module  # Import path should be package1.subpackage1.some_module
+)
 from .. import some_function  # Import path should be package1.subpackage1.some_function
+from .. import some_module  # Import path should be package1.subpackage1.some_module
+from .library import (  # Import path should be package1.subpackage1.subpackage2.library.other_module
+    other_module,
+)
diff --git a/python/private/pypi/dependency_resolver/dependency_resolver.py b/python/private/pypi/dependency_resolver/dependency_resolver.py
index f3a339f..34f2fb1 100644
--- a/python/private/pypi/dependency_resolver/dependency_resolver.py
+++ b/python/private/pypi/dependency_resolver/dependency_resolver.py
@@ -159,7 +159,9 @@
         # Further, shutil.copy preserves the source file's mode, and so if
         # our source file is read-only (the default under Perforce Helix),
         # this scratch file will also be read-only, defeating its purpose.
-        with open(resolved_requirements_file, "rb") as fsrc, open(requirements_out, "wb") as fdst:
+        with open(resolved_requirements_file, "rb") as fsrc, open(
+            requirements_out, "wb"
+        ) as fdst:
             shutil.copyfileobj(fsrc, fdst)
 
     update_command = (
diff --git a/python/private/stage2_bootstrap_template.py b/python/private/stage2_bootstrap_template.py
index 689602d..d0c6e07 100644
--- a/python/private/stage2_bootstrap_template.py
+++ b/python/private/stage2_bootstrap_template.py
@@ -66,7 +66,7 @@
             break
         except (ValueError, KeyError):
             pass
-    if win32_version and win32_version >= '10.0.14393':
+    if win32_version and win32_version >= "10.0.14393":
         return path
 
     # import sysconfig only now to maintain python 2.6 compatibility