(
stub: nodes.OverloadedFuncDef, runtime: MaybeMissing[Any], object_path: list[str]
)
| 1374 | |
| 1375 | @verify.register(nodes.OverloadedFuncDef) |
| 1376 | def verify_overloadedfuncdef( |
| 1377 | stub: nodes.OverloadedFuncDef, runtime: MaybeMissing[Any], object_path: list[str] |
| 1378 | ) -> Iterator[Error]: |
| 1379 | # TODO: support `@type_check_only` decorator |
| 1380 | if isinstance(runtime, Missing): |
| 1381 | yield Error(object_path, "is not present at runtime", stub, runtime) |
| 1382 | return |
| 1383 | |
| 1384 | if stub.is_property: |
| 1385 | # Any property with a setter is represented as an OverloadedFuncDef |
| 1386 | if is_read_only_property(runtime): |
| 1387 | yield Error(object_path, "is read-only at runtime but not in the stub", stub, runtime) |
| 1388 | return |
| 1389 | |
| 1390 | if not is_probably_a_function(runtime): |
| 1391 | yield Error(object_path, "is not a function", stub, runtime) |
| 1392 | if not callable(runtime): |
| 1393 | return |
| 1394 | |
| 1395 | # mypy doesn't allow overloads where one overload is abstract but another isn't, |
| 1396 | # so it should be okay to just check whether the first overload is abstract or not. |
| 1397 | # |
| 1398 | # TODO: Mypy *does* allow properties where e.g. the getter is abstract but the setter is not; |
| 1399 | # and any property with a setter is represented as an OverloadedFuncDef internally; |
| 1400 | # not sure exactly what (if anything) we should do about that. |
| 1401 | first_part = stub.items[0] |
| 1402 | if isinstance(first_part, nodes.Decorator) and first_part.is_overload: |
| 1403 | for msg in _verify_abstract_status(first_part.func, runtime): |
| 1404 | yield Error(object_path, msg, stub, runtime) |
| 1405 | |
| 1406 | # Look the object up statically, to avoid binding by the descriptor protocol |
| 1407 | static_runtime = _static_lookup_runtime(object_path) |
| 1408 | |
| 1409 | for message in _verify_static_class_methods(stub, runtime, static_runtime, object_path): |
| 1410 | yield Error(object_path, "is inconsistent, " + message, stub, runtime) |
| 1411 | |
| 1412 | # TODO: Should call _verify_final_method here, |
| 1413 | # but overloaded final methods in stubs cause a stubtest crash: see #14950 |
| 1414 | |
| 1415 | signature = safe_inspect_signature(runtime) |
| 1416 | if not signature: |
| 1417 | return |
| 1418 | |
| 1419 | stub_sig = Signature.from_overloadedfuncdef(stub) |
| 1420 | runtime_sig = Signature.from_inspect_signature(signature) |
| 1421 | |
| 1422 | for message in _verify_signature( |
| 1423 | stub_sig, |
| 1424 | runtime_sig, |
| 1425 | function_name=stub.name, |
| 1426 | warn_runtime_is_object_init=runtime is object.__init__, |
| 1427 | ): |
| 1428 | # TODO: This is a little hacky, but the addition here is super useful |
| 1429 | if "has a default value of type" in message: |
| 1430 | message += ( |
| 1431 | ". This is often caused by overloads failing to account for explicitly passing " |
| 1432 | "in the default value." |
| 1433 | ) |
nothing calls this directly
no test coverage detected
searching dependent graphs…