Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/pynguin/analyses/typesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
import networkx as nx
from networkx.drawing.nx_pydot import to_pydot

if sys.version_info >= (3, 14):
import annotationlib

import pynguin.configuration as config
import pynguin.utils.typetracing as tt
from pynguin.analyses.string_subtypes import infer_regex_from_methods
Expand Down Expand Up @@ -2369,7 +2372,15 @@ def infer_signature(
"""
method_for_signature = get_method_for_signature(method)
try:
method_signature = inspect.signature(method_for_signature)
if sys.version_info >= (3, 14):
# Deferred annotations (PEP 649) may name types imported only for
# type checking, which raises NameError in the default VALUE format.
method_signature = inspect.signature(
method_for_signature,
annotation_format=annotationlib.Format.FORWARDREF,
)
else:
method_signature = inspect.signature(method_for_signature)
except (ValueError, TypeError):
method_signature = inspect.Signature(
parameters=[
Expand Down
11 changes: 11 additions & 0 deletions tests/analyses/test_typesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import inspect
import operator
import re
import sys
from typing import Any, ParamSpec, TypeVar, Union
from unittest import mock

Expand Down Expand Up @@ -192,6 +193,16 @@ def test_infer_type_info(func, infer_types, expected_parameters, expected_return
assert result.return_type == expected_return


@pytest.mark.skipif(sys.version_info < (3, 14), reason="Annotations are deferred from Python 3.14")
def test_infer_type_info_annotation_imported_for_type_checking():
from tests.fixtures.types.deferred_annotations import length # noqa: PLC0415

type_system = TypeSystem()
result = type_system.infer_type_info(length, type_inference_provider=HintInference())
assert list(result.signature.parameters) == ["obj"]
assert result.original_parameters == {"obj": AnyType()}


A = TypeVar("A")


Expand Down
14 changes: 14 additions & 0 deletions tests/fixtures/types/deferred_annotations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# This file is part of Pynguin.
#
# SPDX-FileCopyrightText: 2019–2026 Pynguin Contributors
#
# SPDX-License-Identifier: MIT
#
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from collections.abc import Sized


def length(obj: Sized) -> int:
return len(obj)