Skip to content

Commit bba1a7a

Browse files
committed
fix: request signature with annotation format STRING
1 parent 06e6b3b commit bba1a7a

3 files changed

Lines changed: 46 additions & 2 deletions

File tree

src/pluggy/_hooks.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@
3636
]
3737
_HookImplFunction: TypeAlias = Callable[..., _T | Generator[None, Result[_T], None]]
3838

39+
if sys.version_info >= (3, 14):
40+
from annotationlib import Format
41+
42+
def _signature(func: Callable[..., object]) -> inspect.Signature:
43+
return inspect.signature(func, annotation_format=Format.STRING)
44+
else:
45+
46+
def _signature(func: Callable[..., object]) -> inspect.Signature:
47+
return inspect.signature(func)
48+
3949

4050
class HookspecOpts(TypedDict):
4151
"""Options for a hook specification."""
@@ -310,7 +320,7 @@ def varnames(func: object) -> tuple[tuple[str, ...], tuple[str, ...]]:
310320

311321
try:
312322
# func MUST be a function or method here or we won't parse any args.
313-
sig = inspect.signature(
323+
sig = _signature(
314324
func.__func__ if inspect.ismethod(func) else func # type:ignore[arg-type]
315325
)
316326
except TypeError: # pragma: no cover

src/pluggy/_manager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from ._hooks import _HookImplFunction
1919
from ._hooks import _Namespace
2020
from ._hooks import _Plugin
21+
from ._hooks import _signature
2122
from ._hooks import _SubsetHookCaller
2223
from ._hooks import HookCaller
2324
from ._hooks import HookImpl
@@ -522,4 +523,4 @@ def subset_hook_caller(
522523

523524

524525
def _formatdef(func: Callable[..., object]) -> str:
525-
return f"{func.__name__}{inspect.signature(func)}"
526+
return f"{func.__name__}{_signature(func)}"

testing/test_helpers.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
from collections.abc import Callable
22
from functools import wraps
3+
import sys
34
from typing import Any
45
from typing import cast
6+
from typing import TYPE_CHECKING
57
from typing import TypeVar
68

79
from pluggy._hooks import varnames
810
from pluggy._manager import _formatdef
911

1012

13+
if TYPE_CHECKING:
14+
# Cannot use typing.Tuple due to pyupgrade replacing it with tuple
15+
from non_existent_module import Tuple
16+
17+
1118
def test_varnames() -> None:
1219
def f(x) -> None:
1320
i = 3 # noqa #pragma: no cover
@@ -90,6 +97,32 @@ def function4(arg1, *args, **kwargs):
9097
assert _formatdef(function4) == "function4(arg1, *args, **kwargs)"
9198

9299

100+
def test_varnames_with_annotations() -> None:
101+
if sys.version_info >= (3, 14):
102+
103+
def hook(arg1: Tuple[int]) -> None: # type: ignore[no-any-unimported]
104+
pass
105+
else:
106+
107+
def hook(arg1: "Tuple[int]") -> "None": # type: ignore[no-any-unimported]
108+
pass
109+
110+
assert varnames(hook) == (("arg1",), ())
111+
112+
113+
def test_formatdef_with_annotations() -> None:
114+
if sys.version_info >= (3, 14):
115+
116+
def hook(arg1: Tuple[int]) -> None: # type: ignore[no-any-unimported]
117+
pass
118+
else:
119+
120+
def hook(arg1: "Tuple[int]") -> "None": # type: ignore[no-any-unimported]
121+
pass
122+
123+
assert _formatdef(hook) == "hook(arg1: 'Tuple[int]') -> 'None'"
124+
125+
93126
def test_varnames_decorator() -> None:
94127
F = TypeVar("F", bound=Callable[..., Any])
95128

0 commit comments

Comments
 (0)