Repository: PyCQA/flake8

Issue:
Flake8 hangs on a windows machine with > 61 procs when running on > 1 file
### how did you install flake8?

```console
D:\temp>uv venv flake8
Using CPython 3.10.15
Creating virtual environment at: flake8
Activate with: flake8\Scripts\activate

D:\temp>flake8\Scripts\activate

(flake8) D:\temp>uv pip install flake8
Using Python 3.10.15 environment at: flake8
Resolved 4 packages in 85ms
Prepared 4 packages in 110ms
░░░░░░░░░░░░░░░░░░░░ [0/4] Installing wheels...
Installed 4 packages in 115ms
 + flake8==7.1.1
 + mccabe==0.7.0
 + pycodestyle==2.12.1
 + pyflakes==3.2.0
```

### unmodified output of `flake8 --bug-report`

```json
{
  "platform": {
    "python_implementation": "CPython",
    "python_version": "3.10.15",
    "system": "Windows"
  },
  "plugins": [
    {
      "plugin": "mccabe",
      "version": "0.7.0"
    },
    {
      "plugin": "pycodestyle",
      "version": "2.12.1"
    },
    {
      "plugin": "pyflakes",
      "version": "3.2.0"
    }
  ],
  "version": "7.1.1"
}
```

### describe the problem

#### what I expected to happen

Flake8 should run and exit with defaults from the command line

#### Runs/does not exit (hangs after printing stack trace):

```console
(flake8) D:\temp>flake8 testit0.py testit1.py
Exception in thread Thread-1 (_handle_workers):
Traceback (most recent call last):
  File "lib\threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "lib\threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "lib\multiprocessing\pool.py", line 522, in _handle_workers
    cls._wait_for_updates(current_sentinels, change_notifier)
  File "lib\multiprocessing\pool.py", line 502, in _wait_for_updates
    wait(sentinels, timeout=timeout)
  File "lib\multiprocessing\connection.py", line 879, in wait
    ready_handles = _exhaustive_wait(waithandle_to_obj.keys(), timeout)
  File "lib\multiprocessing\connection.py", line 811, in _exhaustive_wait
    res = _winapi.WaitForMultipleObjects(L, False, timeout)
ValueError: need at most 63 handles, got a sequence of length 194   # <-- hangs here
```

#### Runs/exits (does NOT hang) when constrained to 61 jobs:

```console
(flake8) D:\temp>flake8 testit0.py testit1.py --jobs 61
```

#### See possible fix #1964

Discussion:
@asottile: this issue claims that this is fixed -- what version of windows are you running on? https://github.com/python/cpython/issues/71090 https://github.com/python/cpython/issues/84444@pylbert: Ah, ok - the cpython would be much preferred to a work around here.  I can close my issue and pr.

I'm seeing this on:

Python 3.10.15 with flake8 7.1.0 on Windows Server 2022 Standard 21H2

(note: #1964 originally mentioned Windows 11, this should have been Windows Server 2022 - I've updated the PR text)

Solution patch:
diff --git a/src/flake8/checker.py b/src/flake8/checker.py
index 329a2cc3..ff626796 100644
--- a/src/flake8/checker.py
+++ b/src/flake8/checker.py
@@ -256,6 +256,7 @@ def start(self) -> None:
                 exclude=self.exclude,
             )
         )
+        self.jobs = min(len(self.filenames), self.jobs)
 
     def stop(self) -> None:
         """Stop checking files."""


Test patch:
diff --git a/tests/unit/test_checker_manager.py b/tests/unit/test_checker_manager.py
index 68dd82aa..8d6b3dcf 100644
--- a/tests/unit/test_checker_manager.py
+++ b/tests/unit/test_checker_manager.py
@@ -61,6 +61,16 @@ def test_multiprocessing_cpu_count_not_implemented():
     assert manager.jobs == 0
 
 
+def test_jobs_count_limited_to_file_count():
+    style_guide = style_guide_mock()
+    style_guide.options.jobs = JobsArgument("4")
+    style_guide.options.filenames = ["file1", "file2"]
+    manager = checker.Manager(style_guide, finder.Checkers([], [], []), [])
+    assert manager.jobs == 4
+    manager.start()
+    assert manager.jobs == 2
+
+
 def test_make_checkers():
     """Verify that we create a list of FileChecker instances."""
     style_guide = style_guide_mock()