Skip to content

trestle.core.trestle_base_model

trestle.core.trestle_base_model ¤

Trestle Base Model.

Attributes¤

Model = TypeVar('Model', bound='BaseModel') module-attribute ¤

Classes¤

TrestleBaseModel ¤

Bases: BaseModel


              flowchart TD
              trestle.core.trestle_base_model.TrestleBaseModel[TrestleBaseModel]

              

              click trestle.core.trestle_base_model.TrestleBaseModel href "" "trestle.core.trestle_base_model.TrestleBaseModel"
            

Trestle Base Model. Serves as wrapper around BaseModel for overriding methods.

Source code in trestle/core/trestle_base_model.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
class TrestleBaseModel(BaseModel):
    """Trestle Base Model. Serves as wrapper around BaseModel for overriding methods."""

    @classmethod
    def parse_obj(cls: Type['Model'], obj: Any) -> 'Model':
        """Parse object to the given class."""
        try:
            return super().parse_obj(obj)
        except ValidationError as e:
            # check if failed due to the wrong OSCAL version:
            oscal_version_error = False
            for err in e.errors():
                for field in err['loc']:
                    if field == 'oscal-version':
                        message = err['msg']
                        oscal_version_error = True
                        break
            if oscal_version_error:
                raise TrestleError(f'{message}')
            else:
                raise

    def __str__(self) -> str:
        """Return string representation, unwrapping __root__ if present."""
        if hasattr(self, '__root__'):
            return str(self.__root__)
        return super().__str__()

    def __eq__(self, other: Any) -> bool:
        """Compare with unwrapped __root__ value if present."""
        # Only use custom comparison for __root__ models
        if hasattr(self, '__root__') and '__root__' in self.__fields__:
            if isinstance(other, type(self)):
                return self.__root__ == other.__root__
            return self.__root__ == other
        # For non-__root__ models, use default Pydantic comparison
        return super().__eq__(other)

    def __hash__(self) -> int:
        """Hash the __root__ value if present."""
        if hasattr(self, '__root__'):
            try:
                return hash(self.__root__)
            except TypeError:
                # If __root__ is unhashable, fall back to object hash
                return super().__hash__()
        return super().__hash__()

    def __getattr__(self, name: str) -> Any:
        """Delegate attribute access to __root__ if present and attribute not found."""
        # Avoid infinite recursion by checking if __root__ exists via __dict__
        if '__root__' in self.__dict__ and name != '__root__':
            try:
                return getattr(self.__root__, name)
            except AttributeError:
                pass
        raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'")
Functions¤
__eq__(other) ¤

Compare with unwrapped root value if present.

Source code in trestle/core/trestle_base_model.py
55
56
57
58
59
60
61
62
63
def __eq__(self, other: Any) -> bool:
    """Compare with unwrapped __root__ value if present."""
    # Only use custom comparison for __root__ models
    if hasattr(self, '__root__') and '__root__' in self.__fields__:
        if isinstance(other, type(self)):
            return self.__root__ == other.__root__
        return self.__root__ == other
    # For non-__root__ models, use default Pydantic comparison
    return super().__eq__(other)
__getattr__(name) ¤

Delegate attribute access to root if present and attribute not found.

Source code in trestle/core/trestle_base_model.py
75
76
77
78
79
80
81
82
83
def __getattr__(self, name: str) -> Any:
    """Delegate attribute access to __root__ if present and attribute not found."""
    # Avoid infinite recursion by checking if __root__ exists via __dict__
    if '__root__' in self.__dict__ and name != '__root__':
        try:
            return getattr(self.__root__, name)
        except AttributeError:
            pass
    raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'")
__hash__() ¤

Hash the root value if present.

Source code in trestle/core/trestle_base_model.py
65
66
67
68
69
70
71
72
73
def __hash__(self) -> int:
    """Hash the __root__ value if present."""
    if hasattr(self, '__root__'):
        try:
            return hash(self.__root__)
        except TypeError:
            # If __root__ is unhashable, fall back to object hash
            return super().__hash__()
    return super().__hash__()
__str__() ¤

Return string representation, unwrapping root if present.

Source code in trestle/core/trestle_base_model.py
49
50
51
52
53
def __str__(self) -> str:
    """Return string representation, unwrapping __root__ if present."""
    if hasattr(self, '__root__'):
        return str(self.__root__)
    return super().__str__()
parse_obj(obj) classmethod ¤

Parse object to the given class.

Source code in trestle/core/trestle_base_model.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@classmethod
def parse_obj(cls: Type['Model'], obj: Any) -> 'Model':
    """Parse object to the given class."""
    try:
        return super().parse_obj(obj)
    except ValidationError as e:
        # check if failed due to the wrong OSCAL version:
        oscal_version_error = False
        for err in e.errors():
            for field in err['loc']:
                if field == 'oscal-version':
                    message = err['msg']
                    oscal_version_error = True
                    break
        if oscal_version_error:
            raise TrestleError(f'{message}')
        else:
            raise

handler: python