Files
opencv-MIRROR/modules/python/src2/typing_stubs_generation
Kari Pikkarainen 41ef839c7d Merge pull request #30148 from kari-pikkarainen:fix/python-stubs-optional-output-args-5.x
python: mark documented None output arrays as optional in typing stubs (5.x) 🤖🤖🤖 - #30148

Port of #30139 to 5.x, as requested in https://github.com/opencv/opencv/pull/30139#issuecomment-5994064397. Relates to #30138.

The two commits are cherry-picked from #30139 without code changes. The second commit message is reworded for the 5.x module layout.

**Commit 1:** adds `make_optional_arg` entries to `NODES_TO_REFINE` in `modules/python/src2/typing_stubs_generation/api_refinement.py`. These output arrays are documented and used with `None` in the 5.x samples and tutorials, but the stubs type them as required, so mypy rejects correct code:

| Function | Argument |
|---|---|
| `calcOpticalFlowPyrLK` | `nextPts` |
| `calcOpticalFlowFarneback` | `flow` |
| `normalize` | `dst` |
| `kmeans` | `bestLabels` |
| `drawKeypoints` | `outImage` |
| `drawMatches` | `outImg` |
| `drawMatchesKnn` | `outImg` |

**Commit 2:** skips `NODES_TO_REFINE` entries whose function, class or namespace is absent from the build, as the `dnn`/`cuda` refinements already do. On 5.x this also fixes an existing failure: with `-DBUILD_opencv_calib=OFF`, the `calibrateCamera` entry raises `SymbolNotFoundError` and no stubs are generated at all. A wrong argument name in a present function still raises `RuntimeError`.

### Verification

I ran CMake configure only, then `gen2.py` from this branch and from `5.x` (2d88732) on the generated `gen_python_config.json`, with `PYTHONHASHSEED=0`:

- **Full build:** the only differences are 16 signatures in `cv2/__init__.pyi`. Each listed argument changes from `cv2.typing.MatLike` / `UMat` to `... | None`, across the Mat and UMat overloads, and `drawMatches` has two C++ overloads.
- **`-DBUILD_opencv_video=OFF`:** stubs are generated. The two optical-flow entries are skipped and the other refinements still apply.
- **`-DBUILD_opencv_calib=OFF`:** `5.x` generates no stubs (`SymbolNotFoundError` for `calibrateCamera`). This branch generates them.
- **mypy 2.4.0:** I installed the generated stubs as a stub-only package and type-checked calls that pass `None` for each argument, e.g. `cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX)`. With the `5.x` stubs there are 11 `call-overload` errors; with this branch there are none.

Builds without `features` still fail for a separate reason, the `Feature2D` aliases in `predefined_types.py`. I'll address that in a follow-up.

_Prepared with AI assistance (Claude Code); I reviewed the change and the verification results._

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-10-06 08:40:49 +03:00
..
2025-07-22 09:47:19 +03:00