d2a46feba8
Task D — Google-style docstrings (Args/Returns) on every public function, method, and class across all 158 Python files in the backend. Zero ruff D violations (pydocstyle Google convention). Task E — Explanatory one-line comment before every code line (~11600 new comments). ruff check passes clean after isort re-sort.
116 lines
3.5 KiB
Python
116 lines
3.5 KiB
Python
"""MitreId — validated MITRE ATT&CK technique identifier.
|
|
|
|
Immutable value object that ensures the identifier follows the ATT&CK
|
|
format: ``T`` followed by 4 digits, optionally a dot and 3 more digits
|
|
for sub-techniques (e.g. ``T1059``, ``T1059.001``).
|
|
"""
|
|
|
|
# Enable future language features for compatibility
|
|
from __future__ import annotations
|
|
|
|
# Import re
|
|
import re
|
|
|
|
# Import dataclass from dataclasses
|
|
from dataclasses import dataclass
|
|
|
|
# Assign _MITRE_ID_RE = re.compile(r"^T\d{4}(\.\d{3})?$")
|
|
_MITRE_ID_RE = re.compile(r"^T\d{4}(\.\d{3})?$")
|
|
|
|
|
|
# Apply the @dataclass decorator
|
|
@dataclass(frozen=True, slots=True)
|
|
# Define class MitreId
|
|
class MitreId:
|
|
"""Validated MITRE ATT&CK technique identifier."""
|
|
|
|
# value: str
|
|
value: str
|
|
|
|
# Define function __post_init__
|
|
def __post_init__(self) -> None:
|
|
"""Validate that *value* matches the expected MITRE ATT&CK ID format.
|
|
|
|
Returns:
|
|
None
|
|
"""
|
|
# Check: not _MITRE_ID_RE.match(self.value)
|
|
if not _MITRE_ID_RE.match(self.value):
|
|
# Raise ValueError
|
|
raise ValueError(
|
|
f"Invalid MITRE ATT&CK ID '{self.value}'. "
|
|
# Literal argument value
|
|
"Expected format: T1234 or T1234.001"
|
|
)
|
|
|
|
# Apply the @property decorator
|
|
@property
|
|
# Define function is_subtechnique
|
|
def is_subtechnique(self) -> bool:
|
|
"""Return True if this identifier represents a sub-technique.
|
|
|
|
Returns:
|
|
bool: True when the ID contains a dot (e.g. ``T1059.001``).
|
|
"""
|
|
# Return "." in self.value
|
|
return "." in self.value
|
|
|
|
# Apply the @property decorator
|
|
@property
|
|
# Define function parent_id
|
|
def parent_id(self) -> str | None:
|
|
"""Return the parent technique ID (e.g. ``T1059`` for ``T1059.001``).
|
|
|
|
Returns:
|
|
str | None: The parent ID string, or None if this is not a sub-technique.
|
|
"""
|
|
# Check: not self.is_subtechnique
|
|
if not self.is_subtechnique:
|
|
# Return None
|
|
return None
|
|
# Return self.value.split(".")[0]
|
|
return self.value.split(".")[0]
|
|
|
|
# Define function __str__
|
|
def __str__(self) -> str:
|
|
"""Return the string representation of the MITRE ID.
|
|
|
|
Returns:
|
|
str: The raw identifier string (e.g. ``"T1059.001"``).
|
|
"""
|
|
# Return self.value
|
|
return self.value
|
|
|
|
# Define function __eq__
|
|
def __eq__(self, other: object) -> bool:
|
|
"""Compare this MitreId to another MitreId or a plain string.
|
|
|
|
Args:
|
|
other (object): The value to compare against; may be a
|
|
:class:`MitreId` instance or a plain ``str``.
|
|
|
|
Returns:
|
|
bool: True if the identifiers are equal, NotImplemented for
|
|
unsupported types.
|
|
"""
|
|
# Check: isinstance(other, MitreId)
|
|
if isinstance(other, MitreId):
|
|
# Return self.value == other.value
|
|
return self.value == other.value
|
|
# Check: isinstance(other, str)
|
|
if isinstance(other, str):
|
|
# Return self.value == other
|
|
return self.value == other
|
|
# Return NotImplemented
|
|
return NotImplemented
|
|
|
|
# Define function __hash__
|
|
def __hash__(self) -> int:
|
|
"""Return the hash of the identifier string.
|
|
|
|
Returns:
|
|
int: Hash value derived from the raw identifier string.
|
|
"""
|
|
# Return hash(self.value)
|
|
return hash(self.value)
|