Skip to content

Commit eab3524

Browse files
context_management: add a type stub override to fix typing (#457)
context_management: add a type stub override to fix typing Type checkers (mypy, pyright, et al.) don't understand the ContextManager descriptor class. With a stub file, we can tell the type checker to treat ContextManager as a simple decorator function which is something that it understands. from typing import reveal_type import specfile s = specfile.Specfile("./fedora/python-specfile.spec") # Before: types.MethodType # After: (allow_duplicates: bool = False, default_to_implicit_numbering: bool = False, default_source_number_digits: int = 1) -> GeneratorContextManager[Sources] reveal_type(s.sources) # Before: Any # After: GeneratorContextManager[Sources] reveal_type(s.sources()) # Before: Any # After: Sources reveal_type(s.sources().__enter__()) reveal_type(s.sources().content) RELEASE NOTES BEGIN context_management: add a type stub override to fix typing. Type checkers like mypy and pyright can now correctly determine the types for .sources(), .sections(), and the other Specfile methods that return context managers. RELEASE NOTES END Reviewed-by: Nikola Forró
2 parents 1133baa + 51565f1 commit eab3524

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ repos:
5151
args: [--show-error-codes, --ignore-missing-imports]
5252
additional_dependencies:
5353
[types-setuptools, types-requests, types-python-dateutil]
54+
# This file is overridden by a type stub
55+
exclude: "specfile/context_management.py"
5456
- repo: https://github.com/teemtee/tmt.git
5557
rev: 1.41.0
5658
hooks:

specfile/context_management.pyi

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright Contributors to the Packit project.
2+
# SPDX-License-Identifier: MIT
3+
4+
import contextlib
5+
from collections.abc import Iterator
6+
from typing import Callable, Generator, ParamSpec, TypeVar
7+
8+
_T_co = TypeVar("_T_co", covariant=True)
9+
_P = ParamSpec("_P")
10+
11+
@contextlib.contextmanager
12+
def capture_stderr() -> Generator[list[bytes], None, None]: ...
13+
14+
class GeneratorContextManager(contextlib._GeneratorContextManager[_T_co]):
15+
def __init__(self, function: Callable[..., _T_co]) -> None: ...
16+
def __del__(self) -> None: ...
17+
@property
18+
def content(self) -> _T_co: ...
19+
20+
# Instead of the original descriptor class, tell the type checker to treat
21+
# ContextManager as a simple decorator function which is something that it
22+
# understands.
23+
def ContextManager(
24+
func: Callable[_P, Iterator[_T_co]],
25+
) -> Callable[_P, GeneratorContextManager[_T_co]]: ...

0 commit comments

Comments
 (0)