mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04:00
Clean up stale typing stubs during incremental builds
When a module is disabled in an incremental build (e.g. switching from -DBUILD_opencv_gapi=ON to OFF), its typing stub directory persists from the previous build. The stubs generator only creates directories for enabled modules but never removes old ones, and the copy step merges rather than replaces, so stale .pyi files propagate to both the loader directory and the install prefix. This causes type-checkers (mypy, pyright) to report errors for stubs that reference symbols from modules that are no longer available. Fix both propagation paths: - generation.py: remove all subdirectories under the stubs output root before regenerating, so only currently enabled module stubs exist in the build directory. Top-level files (py.typed) are preserved. - copy_typings_stubs_on_success.py: remove stale .pyi files and py.typed markers from the loader directory before copying fresh stubs, so leftover stubs from a previous copy are cleaned up. Runtime .py files are not affected.
This commit is contained in:
@@ -3,6 +3,7 @@ __all__ = ("generate_typing_stubs", )
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shutil
|
||||
from typing import (Callable, NamedTuple, Union, Set, Dict,
|
||||
Collection, Tuple, List)
|
||||
import warnings
|
||||
@@ -24,6 +25,22 @@ from .nodes.type_node import (TypeNode, AliasTypeNode, AliasRefTypeNode,
|
||||
ConditionalAliasTypeNode, PrimitiveTypeNode)
|
||||
|
||||
|
||||
def _clean_stale_stubs_dirs(stubs_root: Path) -> None:
|
||||
"""Remove all subdirectories under stubs_root.
|
||||
|
||||
During incremental builds, disabling a previously enabled module leaves
|
||||
behind its typing stub directory (e.g. cv2/gapi/). Removing all
|
||||
subdirectories before regeneration ensures only stubs for currently
|
||||
enabled modules are present. Top-level files (py.typed, __init__.pyi)
|
||||
are kept because they are managed separately.
|
||||
"""
|
||||
if not stubs_root.is_dir():
|
||||
return
|
||||
for item in stubs_root.iterdir():
|
||||
if item.is_dir():
|
||||
shutil.rmtree(item)
|
||||
|
||||
|
||||
def generate_typing_stubs(root: NamespaceNode, output_path: Path):
|
||||
"""Generates typing stubs for the AST with root `root` and outputs
|
||||
created files tree to directory pointed by `output_path`.
|
||||
@@ -88,6 +105,12 @@ def generate_typing_stubs(root: NamespaceNode, output_path: Path):
|
||||
# The whole process should fail !only! when all possible scopes are
|
||||
# checked and at least 1 node is still unresolved.
|
||||
root.resolve_type_nodes()
|
||||
# Remove stale typing stub subdirectories from previous builds.
|
||||
# In incremental builds, disabling a module (e.g. -DBUILD_opencv_gapi=OFF)
|
||||
# no longer generates its stubs, but leftover directories from a previous
|
||||
# build persist and propagate through the copy/install steps, causing
|
||||
# type-checker errors for stubs referencing unavailable modules.
|
||||
_clean_stale_stubs_dirs(Path(output_path) / root.export_name)
|
||||
_generate_typing_module(root, output_path)
|
||||
_populate_reexported_symbols(root)
|
||||
_generate_typing_stubs(root, output_path)
|
||||
|
||||
Reference in New Issue
Block a user