From cb6c7884884dd7e81bb7ed09697a707cffd55fd2 Mon Sep 17 00:00:00 2001 From: Peter Holloway Date: Fri, 26 Jun 2026 14:13:35 +0100 Subject: [PATCH] fix: Ignore NameError when introspecting plan functions When getting type hints to determine if a function is a plan, a `NameError` can be raised (specifically when checking `pydantic.Field` in this case) and the context loading crashes. Ignoring the error in the same way that we ignore `TypeError` allows us to ignore broken types. As we are only interested in specific return types (`Generator`) this shouldn't affect which functions are treated as plans. Specific symptoms/causes: In pydantic `Field` has an argument with a type hint of (via an alias or two) `JsonValue`. This is defined as a recursive alias JsonValue: TypeAlias = Union[int, float, str, bool, None, list['JsonValue'], 'JsonDict'] JsonDict: TypeAlias = dict[str, JsonValue] when `get_type_hints` is called on `Field` a `NameError` is raised. This can be seen in a python repl >>> from typing import get_type_hints >>> from pydantic import Field >>> get_type_hints(Field) Traceback (most recent call last): ... NameError: name 'JsonValue' is not defined In blueapi, this is a problem if any module included via a PlanSource has `Field` as a top level object. --- src/blueapi/core/bluesky_types.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/blueapi/core/bluesky_types.py b/src/blueapi/core/bluesky_types.py index d05904a926..64a2a5289e 100644 --- a/src/blueapi/core/bluesky_types.py +++ b/src/blueapi/core/bluesky_types.py @@ -75,8 +75,9 @@ def is_bluesky_plan_generator(func: PlanGenerator) -> bool: return (get_origin(return_type) == Generator) and ( get_args(return_type)[0] == Msg ) - except TypeError: - # get_type_hints fails on some objects (such as Union or Optional) + except (TypeError, NameError): + # get_type_hints fails on some objects (such as Union, Optional or + # pydantic.Field) return False