|
@@ -48,6 +48,19 @@ class Results(SimpleNamespace):
|
|
|
return self.__getattribute__(subscript)
|
|
return self.__getattribute__(subscript)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def _chain_attrs(context: Any, ref: Ref) -> Any:
|
|
|
|
|
+ try:
|
|
|
|
|
+ for token in ref.path:
|
|
|
|
|
+ if isinstance(context, dict):
|
|
|
|
|
+ context = context[token]
|
|
|
|
|
+ else:
|
|
|
|
|
+ context = getattr(context, token)
|
|
|
|
|
+ return context
|
|
|
|
|
+ except (KeyError, AttributeError):
|
|
|
|
|
+ reason = "NULL object" if context is None else "not found"
|
|
|
|
|
+ raise AttributeError(f"unable to find {ref} item \"{token}\": {reason}")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
class Context(SimpleNamespace):
|
|
class Context(SimpleNamespace):
|
|
|
"""Wrapper class for the context of the CI runtime"""
|
|
"""Wrapper class for the context of the CI runtime"""
|
|
|
|
|
|
|
@@ -66,9 +79,7 @@ class Context(SimpleNamespace):
|
|
|
assert len(arg.path) == 2
|
|
assert len(arg.path) == 2
|
|
|
return os.environ.get(arg.path[1])
|
|
return os.environ.get(arg.path[1])
|
|
|
|
|
|
|
|
- return reduce( # type: ignore[return-value]
|
|
|
|
|
- lambda o, a: o[a] if isinstance(o, dict) else getattr(o, a), arg.path, self
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ return _chain_attrs(self, arg)
|
|
|
|
|
|
|
|
@overload
|
|
@overload
|
|
|
def fabricate(
|
|
def fabricate(
|