|
|
@@ -1,7 +1,8 @@
|
|
|
"""Common objects in the CI hierarchy"""
|
|
|
+import re
|
|
|
|
|
|
from dataclasses import dataclass
|
|
|
-from typing import Annotated, Self, final
|
|
|
+from typing import ClassVar, Final, Self, final
|
|
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
@@ -16,19 +17,22 @@ class Outputs(BaseModel):
|
|
|
@final
|
|
|
def validated(self) -> Self:
|
|
|
"""Validate this output object, affirm that it is properly constructed"""
|
|
|
- return self.model_validate(self, extra="forbid")
|
|
|
+ return self.model_validate(vars(self), extra="forbid")
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
class Ref:
|
|
|
"""Annotation class describing a reference into Context or another place"""
|
|
|
|
|
|
- path: list[Annotated[str, Field(pattern="\\w*(_\\w*)*")]]
|
|
|
+ path: list[str]
|
|
|
+ PATTERN: Final[ClassVar[re.Pattern]] = re.compile("[A-Za-z][\\W_]*(_[\\W_]*)*")
|
|
|
|
|
|
def __init__(self, pathstr: str) -> None:
|
|
|
self.path = pathstr.split(".")
|
|
|
- if not self.path:
|
|
|
+ if len(self.path) <= 1:
|
|
|
raise ValueError("References must be of the form A.B.C etc.")
|
|
|
+ if any(not Ref.PATTERN.match(t) for t in self.path):
|
|
|
+ raise ValueError("All path elements in a References must be")
|
|
|
|
|
|
def __repr__(self) -> str:
|
|
|
return "Ref({})".format(".".join(self.path))
|