@@ -1465,3 +1465,55 @@ def test_typevar_cached_by_type_id(self):
14651465 result1 = mapping ._resolve_type (100 )
14661466 result2 = mapping ._resolve_type (100 )
14671467 assert result1 is result2
1468+
1469+
1470+ @requires_ty_types_cli
1471+ class TestImportedNameTypeAttribution :
1472+ """Tests for type attribution of names imported via 'from X import Y'.
1473+
1474+ When a name is imported (e.g. `from typing import Callable`) and then
1475+ used in a type annotation, the identifier's field_type should resolve
1476+ to a JavaType.Class with the fully qualified name, not JavaType.Unknown.
1477+ """
1478+
1479+ def test_typing_callable_has_fqn (self ):
1480+ """typing.Callable in a type annotation should resolve to typing.Callable, not Unknown."""
1481+ source = '''from typing import Callable
1482+ handler: Callable[[int], str] = lambda x: str(x)
1483+ '''
1484+ mapping , tree , tmpdir , client = _make_mapping (source )
1485+ try :
1486+ # handler: Callable[...] — the annotation target 'handler'
1487+ ann_node = tree .body [1 ] # AnnAssign
1488+ # The annotation itself is the Subscript: Callable[[int], str]
1489+ annotation = ann_node .annotation # ast.Subscript
1490+ # annotation.value is the Name node for 'Callable'
1491+ callable_name = annotation .value
1492+ result = mapping .type (callable_name )
1493+ assert result is not None , "Callable name node should have a type"
1494+ assert not isinstance (result , JavaType .Unknown ), \
1495+ f"Expected typing.Callable to resolve to a Class, got Unknown"
1496+ assert isinstance (result , (JavaType .Class , JavaType .FullyQualified )), \
1497+ f"Expected JavaType.Class, got { type (result ).__qualname__ } "
1498+ assert 'typing' in result ._fully_qualified_name , \
1499+ f"Expected FQN containing 'typing', got '{ result ._fully_qualified_name } '"
1500+ finally :
1501+ _cleanup_mapping (mapping , tmpdir , client )
1502+
1503+ def test_typing_callable_qualified_has_fqn (self ):
1504+ """typing.Callable via qualified access should also resolve correctly."""
1505+ source = '''import typing
1506+ handler: typing.Callable[[int], str] = lambda x: str(x)
1507+ '''
1508+ mapping , tree , tmpdir , client = _make_mapping (source )
1509+ try :
1510+ ann_node = tree .body [1 ] # AnnAssign
1511+ annotation = ann_node .annotation # ast.Subscript
1512+ # annotation.value is the Attribute node: typing.Callable
1513+ attr_node = annotation .value # ast.Attribute
1514+ result = mapping .type (attr_node )
1515+ assert result is not None , "typing.Callable attribute node should have a type"
1516+ assert not isinstance (result , JavaType .Unknown ), \
1517+ f"Expected typing.Callable to resolve to a Class, got Unknown"
1518+ finally :
1519+ _cleanup_mapping (mapping , tmpdir , client )
0 commit comments