Source code for dataforge_ml.profiling._base

"""
Abstract base classes for all structural profilers.

Hierarchy
---------
Profiling[R]                    — root: thin ABC, provides _resolve_columns
├── ColumnBatchProfiler[R]      — registry tier: profile(df, columns) processes a
│   │                             typed column batch; no config, no eligibility gates
│   ├── NumericProfiler
│   ├── CategoricalProfiler
│   ├── DatetimeProfiler
│   ├── BooleanProfiler
│   └── TextProfiler
├── DatasetLevelProfiler[R]     — direct-call tier: may have extra __init__ params;
│   │                             not compatible with the SemanticType registry
│   ├── MissingnessProfiler
│   ├── TargetProfiler
│   └── CorrelationProfiler
└── ModalityProfiler            — dataset-shape tier: profile(df) → DatasetStats
    └── TabularProfiler
"""
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Generic, TypeVar

import polars as pl

from ._config import DatasetStats

R = TypeVar("R")


[docs] class OverrideCoercionError(Exception): """ Raised when a user-overridden column completely fails coercion. This exception is triggered when zero usable values remain after coercion, despite the original column having at least one non-null value. """ pass
class Profiling(ABC, Generic[R]): """ Root base for all profilers. Thin ABC — no config state. Sub-processors are pure batch processors: given a DataFrame and a column list, return a result. No routing, no scoping, no config. """ @abstractmethod def profile(self, data: pl.DataFrame, **kwargs) -> R: """ Execute the profiling operation. Parameters ---------- data : pl.DataFrame The dataset to profile. **kwargs : dict Additional arguments for specific profilers. Returns ------- R The profiling result. """ ... def _resolve_columns( self, available: list[str], requested: list[str] | None, ) -> list[str]: if requested is None: return list(available) available_set = set(available) return [c for c in requested if c in available_set] class ColumnBatchProfiler(Profiling[R]): """ Registry-compatible column profiler. Contract -------- - __init__ takes no arguments (instantiated as profiler_cls()). - profile(df, columns) receives the full DataFrame and the list of same-type column names to process. Profiles every column in the list without any internal eligibility gate or config consultation. - Returns a result with: .columns: dict[str, <Stats>] — per-column stats .analysed_columns: list[str] — columns actually profiled """ @abstractmethod def profile(self, data: pl.DataFrame, columns: list[str], user_overrides: set[str] | None = None) -> R: """ Profile a batch of columns of the same semantic type. Parameters ---------- data : pl.DataFrame The dataset containing the columns to profile. columns : list[str] A list of column names to profile. user_overrides : set[str] | None, optional A set of column names that have been manually overridden by the user. Returns ------- R The profiling result containing column statistics. Raises ------ OverrideCoercionError If a column in user_overrides completely fails coercion. """ ... # type: ignore[override] class DatasetLevelProfiler(Profiling[R]): """ Directly-called profiler. May have extra __init__ params (e.g. target_column, numeric_columns). Never registered in the SemanticType registry — always instantiated explicitly with its specific arguments. """ @abstractmethod def profile(self, data: pl.DataFrame, **kwargs) -> R: """ Execute the dataset-level profiling operation. Parameters ---------- data : pl.DataFrame The dataset to profile. **kwargs : dict Additional arguments for specific profilers. Returns ------- R The profiling result. """ ... class ModalityProfiler(Profiling[DatasetStats]): """ Dataset-shape profiler. One concrete implementation per Modality. Returns DatasetStats covering shape, memory, duplicates, sparsity, and chunking metadata. profile(df) takes only the DataFrame — no column list needed. """ @abstractmethod def profile(self, data: pl.DataFrame, **kwargs) -> DatasetStats: """ Execute the dataset-shape profiling operation. Parameters ---------- data : pl.DataFrame The dataset to profile. **kwargs : dict Additional arguments for specific profilers. Returns ------- DatasetStats The dataset statistics. """ ... # type: ignore[override]