Skip to content

Config

docstring_format_checker.config 🔗

Summary

Configuration handling for the docstring format checker.

SectionConfig dataclass 🔗

Configuration for a docstring section.

Source code in src/docstring_format_checker/config.py
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
@dataclass
class SectionConfig:
    """
    Configuration for a docstring section.
    """

    order: int
    name: str
    type: Literal["free_text", "list_name", "list_type", "list_name_and_type"]
    admonition: str = ""
    prefix: str = ""  # Support any prefix string
    required: bool = False
    message: str = ""  # Optional message for validation errors

    def __post_init__(self) -> None:
        """Validate configuration after initialization."""
        if self.type not in VALID_TYPES:
            raise InvalidTypeValuesError(f"Invalid section type: {self.type}. Valid types: {VALID_TYPES}")
__init__ 🔗
__init__(
    order: int,
    name: str,
    type: Literal[
        "free_text",
        "list_name",
        "list_type",
        "list_name_and_type",
    ],
    admonition: str = "",
    prefix: str = "",
    required: bool = False,
    message: str = "",
) -> None
order instance-attribute 🔗
order: int
name instance-attribute 🔗
name: str
type instance-attribute 🔗
type: Literal[
    "free_text",
    "list_name",
    "list_type",
    "list_name_and_type",
]
admonition class-attribute instance-attribute 🔗
admonition: str = ''
prefix class-attribute instance-attribute 🔗
prefix: str = ''
required class-attribute instance-attribute 🔗
required: bool = False
message class-attribute instance-attribute 🔗
message: str = ''
__post_init__ 🔗
__post_init__() -> None

Validate configuration after initialization.

Source code in src/docstring_format_checker/config.py
119
120
121
122
def __post_init__(self) -> None:
    """Validate configuration after initialization."""
    if self.type not in VALID_TYPES:
        raise InvalidTypeValuesError(f"Invalid section type: {self.type}. Valid types: {VALID_TYPES}")

DEFAULT_CONFIG module-attribute 🔗

DEFAULT_CONFIG: list[SectionConfig] = [
    SectionConfig(
        order=1,
        name="summary",
        type="free_text",
        admonition="note",
        prefix="!!!",
        required=True,
    ),
    SectionConfig(
        order=2,
        name="details",
        type="free_text",
        admonition="info",
        prefix="???+",
        required=False,
    ),
    SectionConfig(
        order=3,
        name="params",
        type="list_name_and_type",
        required=True,
    ),
    SectionConfig(
        order=4,
        name="returns",
        type="list_name_and_type",
        required=False,
    ),
    SectionConfig(
        order=5,
        name="yields",
        type="list_type",
        required=False,
    ),
    SectionConfig(
        order=6,
        name="raises",
        type="list_type",
        required=False,
    ),
    SectionConfig(
        order=7,
        name="examples",
        type="free_text",
        admonition="example",
        prefix="???+",
        required=False,
    ),
    SectionConfig(
        order=8,
        name="notes",
        type="free_text",
        admonition="note",
        prefix="???",
        required=False,
    ),
]

load_config 🔗

load_config(
    config_path: Optional[Union[str, Path]] = None,
) -> list[SectionConfig]

Summary

Load configuration from a TOML file or return default configuration.

Parameters:

Name Type Description Default
config_path Optional[Union[str, Path]]

Path to the TOML configuration file. If None, looks for pyproject.toml in current directory. Default: None.

None

Returns:

Type Description
list[SectionConfig]

List of SectionConfig objects defining the docstring sections to check.

Raises:

Type Description
FileNotFoundError

If the specified config file doesn't exist.

InvalidConfigError

If the configuration is invalid.

Source code in src/docstring_format_checker/config.py
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
def load_config(config_path: Optional[Union[str, Path]] = None) -> list[SectionConfig]:
    """
    !!! note "Summary"
        Load configuration from a TOML file or return default configuration.

    Params:
        config_path (Optional[Union[str, Path]]):
            Path to the TOML configuration file.
            If `None`, looks for `pyproject.toml` in current directory.
            Default: `None`.

    Returns:
        (list[SectionConfig]):
            List of SectionConfig objects defining the docstring sections to check.

    Raises:
        (FileNotFoundError):
            If the specified config file doesn't exist.
        (InvalidConfigError):
            If the configuration is invalid.
    """

    if config_path is None:
        # Look for pyproject.toml in current directory
        pyproject_path: Path = Path.cwd().joinpath("pyproject.toml")
        if pyproject_path.exists():
            config_path = pyproject_path
        else:
            return DEFAULT_CONFIG

    config_path = Path(config_path)
    if not config_path.exists():
        raise FileNotFoundError(f"Configuration file not found: {config_path}")

    try:
        with open(config_path, "rb") as f:
            config_data: dict[str, Any] = tomllib.load(f)
    except Exception as e:
        raise InvalidConfigError(f"Failed to parse TOML file {config_path}: {e}") from e

    # Try to find configuration under [tool.dfc] or [tool.docstring-format-checker]
    tool_config = None
    if "tool" in config_data:
        if "dfc" in config_data["tool"]:
            tool_config = config_data["tool"]["dfc"]
        elif "docstring-format-checker" in config_data["tool"]:
            tool_config = config_data["tool"]["docstring-format-checker"]

    if tool_config is None:
        return DEFAULT_CONFIG

    # Parse sections configuration
    sections_config: list[SectionConfig] = []
    if "sections" in tool_config:
        sections_data = tool_config["sections"]
        for section_data in sections_data:
            try:
                section = SectionConfig(
                    order=section_data.get("order", 0),
                    name=section_data.get("name", ""),
                    type=section_data.get("type", ""),
                    admonition=section_data.get("admonition", ""),
                    prefix=section_data.get("prefix", ""),
                    required=section_data.get("required", False),
                )
                sections_config.append(section)
            except (KeyError, TypeError, ValueError, InvalidTypeValuesError) as e:
                raise InvalidConfigError(f"Invalid section configuration: {section_data}. Error: {e}") from e

    if not sections_config:
        return DEFAULT_CONFIG

    # Validate no duplicate order values
    _validate_config_order(config_sections=sections_config)

    # Sort by order
    sections_config.sort(key=lambda x: x.order)

    return sections_config

find_config_file 🔗

find_config_file(
    start_path: Optional[Path] = None,
) -> Optional[Path]

Summary

Find configuration file by searching up the directory tree.

Parameters:

Name Type Description Default
start_path Optional[Path]

Directory to start searching from. If None, resolves to current directory. Default: None.

None

Returns:

Type Description
Optional[Path]

Path to the configuration file if found, None otherwise.

Source code in src/docstring_format_checker/config.py
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
def find_config_file(start_path: Optional[Path] = None) -> Optional[Path]:
    """
    !!! note "Summary"
        Find configuration file by searching up the directory tree.

    Params:
        start_path (Optional[Path]):
            Directory to start searching from.
            If `None`, resolves to current directory.
            Default: `None`.

    Returns:
        (Optional[Path]):
            Path to the configuration file if found, None otherwise.
    """
    if start_path is None:
        start_path = Path.cwd()

    current_path: Path = start_path.resolve()

    while current_path != current_path.parent:
        pyproject_path: Path = current_path.joinpath("pyproject.toml")
        if pyproject_path.exists():
            # Check if it contains dfc configuration
            try:
                with open(pyproject_path, "rb") as f:
                    config_data: dict[str, Any] = tomllib.load(f)
                    if "tool" in config_data and (
                        "dfc" in config_data["tool"] or "docstring-format-checker" in config_data["tool"]
                    ):
                        return pyproject_path
            except Exception:
                pass

        current_path = current_path.parent

    return None