| 263 | @dataclasses.dataclass(eq=True) |
| 264 | @functools.total_ordering |
| 265 | class PatchData: |
| 266 | patch_url: Optional[str] = "" |
| 267 | patch_text: Optional[str] = "" |
| 268 | patch_checksum: Optional[str] = dataclasses.field(init=False, default=None) |
| 269 | |
| 270 | def __post_init__(self): |
| 271 | if not self.patch_url and not self.patch_text: |
| 272 | raise ValueError("A patch must include either patch_url or patch_text") |
| 273 | |
| 274 | if self.patch_text: |
| 275 | self.patch_checksum = compute_patch_checksum(self.patch_text) |
| 276 | |
| 277 | def __lt__(self, other): |
| 278 | if not isinstance(other, PatchData): |
| 279 | return NotImplemented |
| 280 | return self._cmp_key() < other._cmp_key() |
| 281 | |
| 282 | def _cmp_key(self): |
| 283 | return ( |
| 284 | self.patch_url or "", |
| 285 | self.patch_text or "", |
| 286 | self.patch_checksum or "", |
| 287 | ) |
| 288 | |
| 289 | def to_dict(self) -> dict: |
| 290 | """Return a normalized dictionary representation of the commit.""" |
| 291 | return { |
| 292 | "patch_url": self.patch_url, |
| 293 | "patch_text": self.patch_text, |
| 294 | "patch_checksum": self.patch_checksum, |
| 295 | } |
| 296 | |
| 297 | @classmethod |
| 298 | def from_dict(cls, data: dict): |
| 299 | """Create a PatchData instance from a dictionary.""" |
| 300 | return cls( |
| 301 | patch_url=data.get("patch_url"), |
| 302 | patch_text=data.get("patch_text"), |
| 303 | ) |
| 304 | |
| 305 | |
| 306 | class UnMergeablePackageError(Exception): |
no outgoing calls