Resolve annotation created by user with `typing` module and custom objects.
(
annotation: object | str,
context: EvaluationContext,
sig: Signature | None = None,
func: Callable | None = None,
node: ast.Call | None = None,
)
| 1346 | |
| 1347 | |
| 1348 | def _resolve_annotation( |
| 1349 | annotation: object | str, |
| 1350 | context: EvaluationContext, |
| 1351 | sig: Signature | None = None, |
| 1352 | func: Callable | None = None, |
| 1353 | node: ast.Call | None = None, |
| 1354 | ): |
| 1355 | """Resolve annotation created by user with `typing` module and custom objects.""" |
| 1356 | if annotation is None: |
| 1357 | return None |
| 1358 | annotation = _eval_annotation(annotation, context) |
| 1359 | origin = get_origin(annotation) |
| 1360 | if annotation is Self and func and hasattr(func, "__self__"): |
| 1361 | return func.__self__ |
| 1362 | elif origin is Literal: |
| 1363 | type_args = get_args(annotation) |
| 1364 | if len(type_args) == 1: |
| 1365 | return type_args[0] |
| 1366 | elif annotation is LiteralString: |
| 1367 | return "" |
| 1368 | elif annotation is AnyStr: |
| 1369 | index = None |
| 1370 | if func and hasattr(func, "__node__"): |
| 1371 | def_node = func.__node__ |
| 1372 | for i, arg in enumerate(def_node.args.args): |
| 1373 | if not arg.annotation: |
| 1374 | continue |
| 1375 | annotation = _eval_annotation(arg.annotation.id, context) |
| 1376 | if annotation is AnyStr: |
| 1377 | index = i |
| 1378 | break |
| 1379 | is_bound_method = ( |
| 1380 | isinstance(func, MethodType) and getattr(func, "__self__") is not None |
| 1381 | ) |
| 1382 | if index and is_bound_method: |
| 1383 | index -= 1 |
| 1384 | elif sig: |
| 1385 | for i, (key, value) in enumerate(sig.parameters.items()): |
| 1386 | if value.annotation is AnyStr: |
| 1387 | index = i |
| 1388 | break |
| 1389 | if index is None: |
| 1390 | return None |
| 1391 | if index < 0 or index >= len(node.args): |
| 1392 | return None |
| 1393 | return eval_node(node.args[index], context) |
| 1394 | elif origin is TypeGuard: |
| 1395 | return False |
| 1396 | elif origin is set or origin is list: |
| 1397 | # only one type argument allowed |
| 1398 | attributes = [ |
| 1399 | attr |
| 1400 | for attr in dir( |
| 1401 | _resolve_annotation(get_args(annotation)[0], context, sig, func, node) |
| 1402 | ) |
| 1403 | ] |
| 1404 | duck = _Duck(attributes=dict.fromkeys(attributes)) |
| 1405 | return _Duck( |
no test coverage detected
searching dependent graphs…