chore(deps): update pre-commit hooks (#4838)

* chore(deps): update pre-commit hooks

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.281 → v0.0.287](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.281...v0.0.287)
- [github.com/pre-commit/mirrors-mypy: v1.4.1 → v1.5.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.4.1...v1.5.1)
- [github.com/asottile/blacken-docs: 1.15.0 → 1.16.0](https://github.com/asottile/blacken-docs/compare/1.15.0...1.16.0)
- [github.com/Lucas-C/pre-commit-hooks: v1.5.1 → v1.5.4](https://github.com/Lucas-C/pre-commit-hooks/compare/v1.5.1...v1.5.4)
- [github.com/PyCQA/pylint: v3.0.0a6 → v3.0.0a7](https://github.com/PyCQA/pylint/compare/v3.0.0a6...v3.0.0a7)

* style: pre-commit fixes

* Update pyproject.toml

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4102ee3..f1fb4ae 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -38,14 +38,14 @@
 
 # Ruff, the Python auto-correcting linter written in Rust
 - repo: https://github.com/astral-sh/ruff-pre-commit
-  rev: v0.0.281
+  rev: v0.0.287
   hooks:
   - id: ruff
     args: ["--fix", "--show-fixes"]
 
 # Check static types with mypy
 - repo: https://github.com/pre-commit/mirrors-mypy
-  rev: "v1.4.1"
+  rev: "v1.5.1"
   hooks:
   - id: mypy
     args: []
@@ -84,7 +84,7 @@
 
 # Also code format the docs
 - repo: https://github.com/asottile/blacken-docs
-  rev: "1.15.0"
+  rev: "1.16.0"
   hooks:
   - id: blacken-docs
     additional_dependencies:
@@ -92,7 +92,7 @@
 
 # Changes tabs to spaces
 - repo: https://github.com/Lucas-C/pre-commit-hooks
-  rev: "v1.5.1"
+  rev: "v1.5.4"
   hooks:
   - id: remove-tabs
 
@@ -147,7 +147,7 @@
 
 # PyLint has native support - not always usable, but works for us
 - repo: https://github.com/PyCQA/pylint
-  rev: "v3.0.0a6"
+  rev: "v3.0.0a7"
   hooks:
   - id: pylint
     files: ^pybind11
diff --git a/docs/benchmark.py b/docs/benchmark.py
index 2150b6c..fb49fd0 100644
--- a/docs/benchmark.py
+++ b/docs/benchmark.py
@@ -70,7 +70,7 @@
 
 for codegen in [generate_dummy_code_pybind11, generate_dummy_code_boost]:
     print("{")
-    for i in range(0, 10):
+    for i in range(10):
         nclasses = 2**i
         with open("test.cpp", "w") as f:
             f.write(codegen(nclasses))
diff --git a/pyproject.toml b/pyproject.toml
index 59c15ea..ef2a873 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -94,5 +94,5 @@
 isort.known-first-party = ["env", "pybind11_cross_module_tests", "pybind11_tests"]
 
 [tool.ruff.per-file-ignores]
-"tests/**" = ["EM", "N"]
+"tests/**" = ["EM", "N", "E721"]
 "tests/test_call_policies.py" = ["PLC1901"]
diff --git a/tests/test_stl_binders.py b/tests/test_stl_binders.py
index e002f5b..79923f4 100644
--- a/tests/test_stl_binders.py
+++ b/tests/test_stl_binders.py
@@ -209,7 +209,7 @@
 def test_noncopyable_containers():
     # std::vector
     vnc = m.get_vnc(5)
-    for i in range(0, 5):
+    for i in range(5):
         assert vnc[i].value == i + 1
 
     for i, j in enumerate(vnc, start=1):
@@ -217,7 +217,7 @@
 
     # std::deque
     dnc = m.get_dnc(5)
-    for i in range(0, 5):
+    for i in range(5):
         assert dnc[i].value == i + 1
 
     i = 1
@@ -252,7 +252,7 @@
     # nested std::map<std::vector>
     nvnc = m.get_nvnc(5)
     for i in range(1, 6):
-        for j in range(0, 5):
+        for j in range(5):
             assert nvnc[i][j].value == j + 1
 
     # Note: maps do not have .values()