1111from pathlib import Path
1212from typing import Generator , Iterable , Optional , Union
1313
14- import attrs
1514import docx
1615from docx .document import Document as DocumentType
1716from docx .oxml .table import CT_Tbl
1817from docx .oxml .text .paragraph import CT_P
1918from docx .table import Table , _Cell
2019from docx .text .paragraph import Paragraph
20+ from pydantic import BaseModel , ConfigDict , Field
2121
2222_logger = logging .getLogger (__name__ )
2323
@@ -149,14 +149,15 @@ def _table_is_first_ebd_table(table: Table) -> bool:
149149 return "prüfende rolle" in table .rows [0 ].cells [0 ].text .lower ()
150150
151151
152- @attrs .define (kw_only = True , frozen = True )
153- class EbdNoTableSection :
152+ class EbdNoTableSection (BaseModel ):
154153 """
155154 Represents an empty section in the document
156155 """
157156
158- ebd_key : str = attrs .field (validator = attrs .validators .instance_of (str ))
159- remark : str = attrs .field (validator = attrs .validators .instance_of (str ))
157+ model_config = ConfigDict (frozen = True , extra = "forbid" )
158+
159+ ebd_key : str
160+ remark : str
160161
161162
162163# pylint:disable=too-many-branches
@@ -272,8 +273,7 @@ def get_ebd_docx_tables(docx_file_path: Path, ebd_key: str) -> list[Table] | Ebd
272273
273274
274275# pylint:disable=too-few-public-methods
275- @attrs .define (kw_only = True , frozen = True )
276- class EbdChapterInformation :
276+ class EbdChapterInformation (BaseModel ):
277277 """
278278 Contains information about where an EBD is located within the document.
279279 If the heading is e.g. "5.2.1" we denote this as:
@@ -282,22 +282,14 @@ class EbdChapterInformation:
282282 * subsection 1
283283 """
284284
285- chapter : int = attrs .field (
286- validator = attrs .validators .and_ (attrs .validators .instance_of (int ), attrs .validators .ge (1 ))
287- )
288- chapter_title : Optional [str ] = attrs .field (validator = attrs .validators .optional (attrs .validators .instance_of (str )))
289- section : int = attrs .field (
290- validator = attrs .validators .and_ (attrs .validators .instance_of (int ), attrs .validators .ge (1 ))
291- )
292-
293- section_title : Optional [str ] = attrs .field (validator = attrs .validators .optional (attrs .validators .instance_of (str )))
294- subsection : int = attrs .field (
295- validator = attrs .validators .and_ (attrs .validators .instance_of (int ), attrs .validators .ge (1 ))
296- )
297-
298- subsection_title : Optional [str ] = attrs .field (
299- validator = attrs .validators .optional (attrs .validators .instance_of (str ))
300- )
285+ model_config = ConfigDict (frozen = True )
286+
287+ chapter : int = Field (ge = 1 )
288+ chapter_title : Optional [str ] = None
289+ section : int = Field (ge = 1 )
290+ section_title : Optional [str ] = None
291+ subsection : int = Field (ge = 1 )
292+ subsection_title : Optional [str ] = None
301293
302294
303295def _enrich_paragraphs_with_sections (
0 commit comments