1"""GitLab Issue model implementation.
2
3Implements :any:`/specs/spec_model_mapping` §2.3 for Issue entity mapping.
4"""
5
6from __future__ import annotations
7
8from pydantic import BaseModel, Field, field_validator
9from datetime import datetime
10from typing import Any
11
12from ..rendering.renderer_base import Renderer
13
14
[docs]
15class Issue(BaseModel):
16 """GitLab Issue domain model.
17
18 Implements :any:`/specs/spec_model_mapping` §2.3, mapping the following fields:
19
20 * id (int) - Must be interpretable as int
21 * iid (int) - Must be interpretable as int
22 * project_id (int) - Must be interpretable as int
23 * title (str)
24 * state (str, optional)
25 * web_url (str, optional)
26 * description (str, optional)
27
28 """
29
30 id: int
31 iid: int
32 project_id: int
33 title: str
34 description: str | None = None
35 state: str | None = None
36 web_url: str | None = None
37
[docs]
38 @field_validator("iid", mode="before")
39 @classmethod
40 def validate_iid(cls, v: Any) -> int:
41 """Ensure iid is an int, throw error if not possible."""
42 if v is None:
43 raise ValueError("iid cannot be None")
44 try:
45 return int(v)
46 except (ValueError, TypeError) as e:
47 raise ValueError(
48 f"iid must be interpretable as int, got {type(v).__name__}: {v}"
49 ) from e
50
[docs]
51 @field_validator("id", mode="before")
52 @classmethod
53 def validate_int_fields(cls, v: Any) -> int | None:
54 """Convert string/integer mismatches for numeric fields."""
55 if v is None:
56 return None
57 return Renderer.safe_int(v, v)
58
[docs]
59 @classmethod
60 def from_api_json(cls, data: dict) -> "Issue": # noqa: D401
61 return cls.model_validate(data, from_attributes=False)
62
63 model_config = {"extra": "ignore"}
64
65
66__all__ = ["Issue"]