adc_toolkit.data.validators.no_validator

No-operation validator implementation.

This module provides a pass-through validator that implements the DataValidator protocol without performing any validation. It is useful for scenarios where validation is not required, such as during development, testing, or when working with trusted data sources.

The NoValidator class satisfies the DataValidator protocol interface while bypassing all validation logic, effectively making it a no-op (no operation) implementation. This allows it to be used as a drop-in replacement for actual validators when validation overhead is not desired.

Classes

NoValidator A validator that returns data unchanged without performing validation.

See Also

adc_toolkit.data.abs.DataValidator: Protocol that defines the validator interface.
adc_toolkit.data.validators.gx.GXValidator: Great Expectations-based validator.
adc_toolkit.data.validators.pandera.PanderaValidator: Pandera-based validator.

Notes

Using NoValidator is not recommended for production pipelines where data quality assurance is critical. It should primarily be used in the following scenarios:

  • Development and prototyping: Quickly iterate without validation overhead
  • Testing: Unit tests where validation is mocked or not relevant
  • Trusted data sources: Data from sources with external validation guarantees
  • Performance optimization: Temporary bypass when validation is a bottleneck

When NoValidator is instantiated, it emits a UserWarning to alert developers that validation is disabled. This helps prevent accidental use in production environments.

Examples

Using NoValidator in a validated data catalog:

>>> from adc_toolkit.data.validators.no_validator import NoValidator
>>> validator = NoValidator()
>>> import pandas as pd
>>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
>>> validated_df = validator.validate("my_dataset", df)
>>> validated_df is df  # Returns the same object unchanged
True

Using with the factory method:

>>> validator = NoValidator.in_directory("/path/to/config")
>>> # Path is ignored, always returns a NoValidator instance

Integration with ValidatedDataCatalog (bypassing validation):

>>> from adc_toolkit.data import ValidatedDataCatalog
>>> from adc_toolkit.data.validators.no_validator import NoValidator
>>> catalog = ValidatedDataCatalog(catalog=my_catalog, validator=NoValidator())
>>> # All loads and saves pass through without validation
  1"""
  2No-operation validator implementation.
  3
  4This module provides a pass-through validator that implements the DataValidator
  5protocol without performing any validation. It is useful for scenarios where
  6validation is not required, such as during development, testing, or when working
  7with trusted data sources.
  8
  9The NoValidator class satisfies the DataValidator protocol interface while
 10bypassing all validation logic, effectively making it a no-op (no operation)
 11implementation. This allows it to be used as a drop-in replacement for actual
 12validators when validation overhead is not desired.
 13
 14Classes
 15-------
 16NoValidator
 17    A validator that returns data unchanged without performing validation.
 18
 19See Also
 20--------
 21adc_toolkit.data.abs.DataValidator : Protocol that defines the validator interface.
 22adc_toolkit.data.validators.gx.GXValidator : Great Expectations-based validator.
 23adc_toolkit.data.validators.pandera.PanderaValidator : Pandera-based validator.
 24
 25Notes
 26-----
 27Using NoValidator is not recommended for production pipelines where data quality
 28assurance is critical. It should primarily be used in the following scenarios:
 29
 30- Development and prototyping: Quickly iterate without validation overhead
 31- Testing: Unit tests where validation is mocked or not relevant
 32- Trusted data sources: Data from sources with external validation guarantees
 33- Performance optimization: Temporary bypass when validation is a bottleneck
 34
 35When NoValidator is instantiated, it emits a UserWarning to alert developers
 36that validation is disabled. This helps prevent accidental use in production
 37environments.
 38
 39Examples
 40--------
 41Using NoValidator in a validated data catalog:
 42
 43>>> from adc_toolkit.data.validators.no_validator import NoValidator
 44>>> validator = NoValidator()
 45>>> import pandas as pd
 46>>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
 47>>> validated_df = validator.validate("my_dataset", df)
 48>>> validated_df is df  # Returns the same object unchanged
 49True
 50
 51Using with the factory method:
 52
 53>>> validator = NoValidator.in_directory("/path/to/config")
 54>>> # Path is ignored, always returns a NoValidator instance
 55
 56Integration with ValidatedDataCatalog (bypassing validation):
 57
 58>>> from adc_toolkit.data import ValidatedDataCatalog
 59>>> from adc_toolkit.data.validators.no_validator import NoValidator
 60>>> catalog = ValidatedDataCatalog(catalog=my_catalog, validator=NoValidator())
 61>>> # All loads and saves pass through without validation
 62"""
 63
 64import warnings
 65from pathlib import Path
 66
 67from adc_toolkit.data.abs import Data
 68
 69
 70class NoValidator:
 71    """
 72    A no-operation validator that passes data through without validation.
 73
 74    NoValidator implements the DataValidator protocol but performs no actual
 75    validation. It returns all data unchanged, making it a pass-through or
 76    no-op validator. This is useful in scenarios where validation is not
 77    required, such as during development, testing, or when working with
 78    pre-validated or trusted data sources.
 79
 80    The validator emits a UserWarning upon instantiation to alert developers
 81    that validation is disabled, helping prevent accidental use in production
 82    environments where data quality assurance is critical.
 83
 84    Attributes
 85    ----------
 86    None
 87        This class maintains no internal state.
 88
 89    Methods
 90    -------
 91    validate(name, data)
 92        Return data unchanged without performing any validation.
 93    in_directory(path)
 94        Create a NoValidator instance, ignoring the provided path.
 95
 96    See Also
 97    --------
 98    adc_toolkit.data.abs.DataValidator : Protocol defining validator interface.
 99    adc_toolkit.data.validators.gx.GXValidator : Validator using Great Expectations.
100    adc_toolkit.data.validators.pandera.PanderaValidator : Validator using Pandera.
101    adc_toolkit.data.ValidatedDataCatalog : Catalog that uses validators.
102
103    Notes
104    -----
105    This validator is intentionally minimal and does not maintain any
106    configuration, validation rules, or state. It exists solely to satisfy
107    the DataValidator protocol while bypassing validation logic.
108
109    **When to use NoValidator:**
110
111    - **Development and prototyping**: Quickly iterate on data pipelines
112      without validation overhead slowing down the development cycle.
113    - **Testing**: Unit tests where validation logic is mocked, not relevant,
114      or tested separately.
115    - **Trusted data sources**: Data from sources with external validation
116      guarantees (e.g., validated by another system before ingestion).
117    - **Performance optimization**: Temporary bypass when validation becomes
118      a computational bottleneck and data quality is assured through other means.
119    - **Debugging**: Isolate issues by removing validation from the pipeline.
120
121    **When NOT to use NoValidator:**
122
123    - Production data pipelines where data quality is critical
124    - User-facing applications where invalid data could cause errors
125    - Scenarios where schema drift or data corruption must be detected
126    - Compliance-driven contexts requiring validation audit trails
127
128    **Protocol conformance:**
129
130    NoValidator satisfies the DataValidator protocol by implementing:
131
132    - ``validate(name: str, data: Data) -> Data``: Returns data unchanged
133    - ``in_directory(path: str | Path) -> DataValidator``: Factory method
134
135    The class uses structural subtyping (PEP 544) to conform to the protocol
136    without explicit inheritance.
137
138    Warnings
139    --------
140    UserWarning
141        Issued on instantiation to warn that validation is disabled.
142
143    Examples
144    --------
145    Basic instantiation and usage:
146
147    >>> import pandas as pd
148    >>> from adc_toolkit.data.validators.no_validator import NoValidator
149    >>> validator = NoValidator()
150    UserWarning: Not using any validator is not recommended...
151    >>> df = pd.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
152    >>> result = validator.validate("dataset_name", df)
153    >>> result is df  # Same object returned
154    True
155
156    Using the factory method:
157
158    >>> validator = NoValidator.in_directory("/config/path")
159    >>> # Path is ignored; still returns NoValidator instance
160
161    Integration with ValidatedDataCatalog:
162
163    >>> from adc_toolkit.data import ValidatedDataCatalog
164    >>> from adc_toolkit.data.catalogs.kedro import KedroDataCatalog
165    >>> catalog = KedroDataCatalog.in_directory("config/")
166    >>> validator = NoValidator()
167    >>> validated_catalog = ValidatedDataCatalog(catalog=catalog, validator=validator)
168    >>> # All data passes through without validation
169
170    Testing scenario where validation is not needed:
171
172    >>> def test_data_transformation():
173    ...     # Use NoValidator to focus test on transformation logic
174    ...     validator = NoValidator()
175    ...     input_data = create_test_data()
176    ...     validated = validator.validate("test", input_data)
177    ...     result = transform(validated)
178    ...     assert result.shape == expected_shape
179    """
180
181    def __init__(self) -> None:
182        """
183        Initialize the NoValidator instance.
184
185        Creates a new NoValidator that will pass all data through unchanged.
186        Upon instantiation, a UserWarning is emitted to alert developers that
187        validation is disabled. This warning helps prevent accidental use in
188        production environments where data quality assurance is critical.
189
190        Parameters
191        ----------
192        None
193
194        Returns
195        -------
196        None
197
198        Warns
199        -----
200        UserWarning
201            Always emitted on instantiation, warning that no validation will
202            be performed and recommending the use of an actual validator from
203            the `adc_toolkit.data.validators` module.
204
205        See Also
206        --------
207        in_directory : Factory method for creating NoValidator instances.
208        validate : Method that returns data unchanged.
209
210        Notes
211        -----
212        The warning is emitted with ``stacklevel=2`` to ensure it points to
213        the caller's location rather than this constructor, making it easier
214        to identify where the NoValidator is being instantiated.
215
216        This constructor takes no parameters and maintains no internal state,
217        making all NoValidator instances functionally equivalent.
218
219        Examples
220        --------
221        Instantiating the validator triggers a warning:
222
223        >>> from adc_toolkit.data.validators.no_validator import NoValidator
224        >>> validator = NoValidator()
225        UserWarning: Not using any validator is not recommended. Consider using
226        a validator from the `adc_toolkit.data.validators` module.
227
228        The warning can be suppressed if desired (though not recommended):
229
230        >>> import warnings
231        >>> with warnings.catch_warnings():
232        ...     warnings.simplefilter("ignore", UserWarning)
233        ...     validator = NoValidator()
234        >>> # No warning emitted
235
236        Multiple instances are functionally identical:
237
238        >>> validator1 = NoValidator()
239        >>> validator2 = NoValidator()
240        >>> # Both behave identically
241        """
242        warnings.warn(
243            "Not using any validator is not recommended. "
244            "Consider using a validator from the `adc_toolkit.data.validators` module.",
245            UserWarning,
246            stacklevel=2,
247        )
248
249    @classmethod
250    def in_directory(cls, path: str | Path) -> "NoValidator":  # noqa: ARG003
251        """
252        Create a NoValidator instance from a directory path.
253
254        This factory method implements the DataValidator protocol's required
255        interface for directory-based instantiation. For NoValidator, the path
256        parameter is ignored because no configuration is needed. This method
257        exists purely to satisfy the protocol requirement.
258
259        The method simply delegates to the constructor, which creates a
260        stateless NoValidator instance. The returned validator will pass all
261        data through unchanged regardless of the provided path.
262
263        Parameters
264        ----------
265        path : str or pathlib.Path
266            Path to a configuration directory. This parameter is ignored for
267            NoValidator since no configuration is required. It exists only to
268            maintain interface compatibility with the DataValidator protocol.
269
270        Returns
271        -------
272        NoValidator
273            A new NoValidator instance that will return all data unchanged.
274
275        Warns
276        -----
277        UserWarning
278            Issued during instantiation (via ``__init__``) warning that
279            validation is disabled.
280
281        See Also
282        --------
283        __init__ : Constructor that creates the NoValidator instance.
284        validate : Method that returns data unchanged.
285        adc_toolkit.data.abs.DataValidator : Protocol defining this interface.
286
287        Notes
288        -----
289        Unlike actual validator implementations (GXValidator, PanderaValidator),
290        NoValidator does not read any configuration files from the provided
291        directory. The path parameter is accepted and ignored to maintain
292        protocol compatibility.
293
294        This design allows NoValidator to be used as a drop-in replacement for
295        other validators without changing the calling code's interface.
296
297        The ``# noqa: ARG003`` comment suppresses linting warnings about the
298        unused ``path`` parameter, which is intentionally unused.
299
300        Examples
301        --------
302        Creating a NoValidator using the factory method:
303
304        >>> from adc_toolkit.data.validators.no_validator import NoValidator
305        >>> validator = NoValidator.in_directory("/path/to/config")
306        UserWarning: Not using any validator is not recommended...
307        >>> # Path is ignored
308
309        The path parameter has no effect on behavior:
310
311        >>> validator1 = NoValidator.in_directory("/some/path")
312        >>> validator2 = NoValidator.in_directory("/different/path")
313        >>> # Both validators behave identically
314
315        Using with ValidatedDataCatalog's factory method:
316
317        >>> from adc_toolkit.data import ValidatedDataCatalog
318        >>> # If config directory contains NoValidator configuration
319        >>> catalog = ValidatedDataCatalog.in_directory("config/")
320        >>> # Internally calls NoValidator.in_directory()
321
322        Drop-in replacement for other validators:
323
324        >>> # Switch from GXValidator to NoValidator without code changes
325        >>> # Before:
326        >>> # validator = GXValidator.in_directory("validations/")
327        >>> # After (for testing):
328        >>> validator = NoValidator.in_directory("validations/")
329        >>> # Same interface, no validation performed
330        """
331        return cls()
332
333    def validate(self, name: str, data: Data) -> Data:  # noqa: ARG002
334        """
335        Return data unchanged without performing any validation.
336
337        This method implements the DataValidator protocol's validate interface
338        as a no-operation (no-op) pass-through. It accepts a dataset and
339        immediately returns it without performing any validation checks, schema
340        verification, or data quality assessments.
341
342        Unlike actual validator implementations, this method does not check
343        column names, data types, value ranges, null constraints, or any other
344        validation rules. The returned data is the exact same object passed as
345        input, with no modifications or metadata additions.
346
347        Parameters
348        ----------
349        name : str
350            The name identifying the dataset being validated. For NoValidator,
351            this parameter is ignored since no validation is performed. It
352            exists only to maintain interface compatibility with the
353            DataValidator protocol.
354        data : Data
355            The dataset to validate (or rather, to pass through unchanged).
356            Must be a Data protocol-compatible object such as pandas.DataFrame,
357            pyspark.sql.DataFrame, or any object with ``columns`` and ``dtypes``
358            properties.
359
360        Returns
361        -------
362        Data
363            The exact same data object that was passed as input, with no
364            modifications, transformations, or validation metadata attached.
365            The returned value is identical (``is`` relationship) to the input.
366
367        Raises
368        ------
369        None
370            This method never raises validation-related exceptions. It is
371            guaranteed to return the input data unchanged.
372
373        See Also
374        --------
375        __init__ : Constructor that creates the NoValidator instance.
376        in_directory : Factory method for instantiation.
377        adc_toolkit.data.abs.DataValidator.validate : Protocol method definition.
378
379        Notes
380        -----
381        **No-op behavior:**
382
383        This method is intentionally a no-operation. It does not:
384
385        - Check schema (column names, data types, structure)
386        - Validate constraints (null checks, uniqueness, ranges)
387        - Verify statistical properties (distributions, outliers)
388        - Execute business rules or custom validation logic
389        - Log validation results or maintain audit trails
390        - Modify or transform the data in any way
391        - Attach validation metadata to the returned data
392
393        **Identity preservation:**
394
395        The returned data is the exact same object reference as the input:
396
397        >>> result = validator.validate("name", data)
398        >>> result is data  # Always True
399
400        **Parameter usage:**
401
402        The ``name`` parameter is accepted but ignored (hence ``# noqa: ARG002``).
403        In actual validators, this parameter identifies which validation suite
404        to execute. For NoValidator, it has no effect on behavior.
405
406        **Thread safety:**
407
408        Since this method maintains no state and performs no I/O, it is
409        inherently thread-safe. Multiple threads can call validate
410        concurrently without synchronization.
411
412        **Performance:**
413
414        This method has O(1) time complexity and negligible overhead, making
415        it suitable for performance-critical scenarios where validation is
416        bypassed.
417
418        Examples
419        --------
420        Basic validation (no-op) with pandas DataFrame:
421
422        >>> import pandas as pd
423        >>> from adc_toolkit.data.validators.no_validator import NoValidator
424        >>> validator = NoValidator()
425        >>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
426        >>> result = validator.validate("my_dataset", df)
427        >>> result is df
428        True
429        >>> # Data passes through completely unchanged
430
431        The name parameter has no effect:
432
433        >>> result1 = validator.validate("dataset_1", df)
434        >>> result2 = validator.validate("dataset_2", df)
435        >>> result1 is df and result2 is df
436        True
437
438        No validation means invalid data passes through:
439
440        >>> invalid_df = pd.DataFrame({"x": [None, None, None]})
441        >>> # In real validator, this might fail null checks
442        >>> result = validator.validate("strict_schema", invalid_df)
443        >>> result is invalid_df  # Passes through anyway
444        True
445
446        Integration with ValidatedDataCatalog:
447
448        >>> from adc_toolkit.data import ValidatedDataCatalog
449        >>> catalog = ValidatedDataCatalog(catalog=my_catalog, validator=NoValidator())
450        >>> # Load data without validation
451        >>> df = catalog.load("dataset_name")
452        >>> # Save data without validation
453        >>> catalog.save("output_name", df)
454
455        Using in a data pipeline (bypass validation during development):
456
457        >>> def pipeline(validator: DataValidator) -> None:
458        ...     raw = load_raw_data()
459        ...     validated_raw = validator.validate("raw", raw)
460        ...     processed = transform(validated_raw)
461        ...     validated_processed = validator.validate("processed", processed)
462        ...     save(validated_processed)
463        >>> # Development: use NoValidator to skip validation
464        >>> pipeline(NoValidator())
465        >>> # Production: use actual validator
466        >>> # pipeline(GXValidator.in_directory("validations/"))
467        """
468        return data
class NoValidator:
 71class NoValidator:
 72    """
 73    A no-operation validator that passes data through without validation.
 74
 75    NoValidator implements the DataValidator protocol but performs no actual
 76    validation. It returns all data unchanged, making it a pass-through or
 77    no-op validator. This is useful in scenarios where validation is not
 78    required, such as during development, testing, or when working with
 79    pre-validated or trusted data sources.
 80
 81    The validator emits a UserWarning upon instantiation to alert developers
 82    that validation is disabled, helping prevent accidental use in production
 83    environments where data quality assurance is critical.
 84
 85    Attributes
 86    ----------
 87    None
 88        This class maintains no internal state.
 89
 90    Methods
 91    -------
 92    validate(name, data)
 93        Return data unchanged without performing any validation.
 94    in_directory(path)
 95        Create a NoValidator instance, ignoring the provided path.
 96
 97    See Also
 98    --------
 99    adc_toolkit.data.abs.DataValidator : Protocol defining validator interface.
100    adc_toolkit.data.validators.gx.GXValidator : Validator using Great Expectations.
101    adc_toolkit.data.validators.pandera.PanderaValidator : Validator using Pandera.
102    adc_toolkit.data.ValidatedDataCatalog : Catalog that uses validators.
103
104    Notes
105    -----
106    This validator is intentionally minimal and does not maintain any
107    configuration, validation rules, or state. It exists solely to satisfy
108    the DataValidator protocol while bypassing validation logic.
109
110    **When to use NoValidator:**
111
112    - **Development and prototyping**: Quickly iterate on data pipelines
113      without validation overhead slowing down the development cycle.
114    - **Testing**: Unit tests where validation logic is mocked, not relevant,
115      or tested separately.
116    - **Trusted data sources**: Data from sources with external validation
117      guarantees (e.g., validated by another system before ingestion).
118    - **Performance optimization**: Temporary bypass when validation becomes
119      a computational bottleneck and data quality is assured through other means.
120    - **Debugging**: Isolate issues by removing validation from the pipeline.
121
122    **When NOT to use NoValidator:**
123
124    - Production data pipelines where data quality is critical
125    - User-facing applications where invalid data could cause errors
126    - Scenarios where schema drift or data corruption must be detected
127    - Compliance-driven contexts requiring validation audit trails
128
129    **Protocol conformance:**
130
131    NoValidator satisfies the DataValidator protocol by implementing:
132
133    - ``validate(name: str, data: Data) -> Data``: Returns data unchanged
134    - ``in_directory(path: str | Path) -> DataValidator``: Factory method
135
136    The class uses structural subtyping (PEP 544) to conform to the protocol
137    without explicit inheritance.
138
139    Warnings
140    --------
141    UserWarning
142        Issued on instantiation to warn that validation is disabled.
143
144    Examples
145    --------
146    Basic instantiation and usage:
147
148    >>> import pandas as pd
149    >>> from adc_toolkit.data.validators.no_validator import NoValidator
150    >>> validator = NoValidator()
151    UserWarning: Not using any validator is not recommended...
152    >>> df = pd.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
153    >>> result = validator.validate("dataset_name", df)
154    >>> result is df  # Same object returned
155    True
156
157    Using the factory method:
158
159    >>> validator = NoValidator.in_directory("/config/path")
160    >>> # Path is ignored; still returns NoValidator instance
161
162    Integration with ValidatedDataCatalog:
163
164    >>> from adc_toolkit.data import ValidatedDataCatalog
165    >>> from adc_toolkit.data.catalogs.kedro import KedroDataCatalog
166    >>> catalog = KedroDataCatalog.in_directory("config/")
167    >>> validator = NoValidator()
168    >>> validated_catalog = ValidatedDataCatalog(catalog=catalog, validator=validator)
169    >>> # All data passes through without validation
170
171    Testing scenario where validation is not needed:
172
173    >>> def test_data_transformation():
174    ...     # Use NoValidator to focus test on transformation logic
175    ...     validator = NoValidator()
176    ...     input_data = create_test_data()
177    ...     validated = validator.validate("test", input_data)
178    ...     result = transform(validated)
179    ...     assert result.shape == expected_shape
180    """
181
182    def __init__(self) -> None:
183        """
184        Initialize the NoValidator instance.
185
186        Creates a new NoValidator that will pass all data through unchanged.
187        Upon instantiation, a UserWarning is emitted to alert developers that
188        validation is disabled. This warning helps prevent accidental use in
189        production environments where data quality assurance is critical.
190
191        Parameters
192        ----------
193        None
194
195        Returns
196        -------
197        None
198
199        Warns
200        -----
201        UserWarning
202            Always emitted on instantiation, warning that no validation will
203            be performed and recommending the use of an actual validator from
204            the `adc_toolkit.data.validators` module.
205
206        See Also
207        --------
208        in_directory : Factory method for creating NoValidator instances.
209        validate : Method that returns data unchanged.
210
211        Notes
212        -----
213        The warning is emitted with ``stacklevel=2`` to ensure it points to
214        the caller's location rather than this constructor, making it easier
215        to identify where the NoValidator is being instantiated.
216
217        This constructor takes no parameters and maintains no internal state,
218        making all NoValidator instances functionally equivalent.
219
220        Examples
221        --------
222        Instantiating the validator triggers a warning:
223
224        >>> from adc_toolkit.data.validators.no_validator import NoValidator
225        >>> validator = NoValidator()
226        UserWarning: Not using any validator is not recommended. Consider using
227        a validator from the `adc_toolkit.data.validators` module.
228
229        The warning can be suppressed if desired (though not recommended):
230
231        >>> import warnings
232        >>> with warnings.catch_warnings():
233        ...     warnings.simplefilter("ignore", UserWarning)
234        ...     validator = NoValidator()
235        >>> # No warning emitted
236
237        Multiple instances are functionally identical:
238
239        >>> validator1 = NoValidator()
240        >>> validator2 = NoValidator()
241        >>> # Both behave identically
242        """
243        warnings.warn(
244            "Not using any validator is not recommended. "
245            "Consider using a validator from the `adc_toolkit.data.validators` module.",
246            UserWarning,
247            stacklevel=2,
248        )
249
250    @classmethod
251    def in_directory(cls, path: str | Path) -> "NoValidator":  # noqa: ARG003
252        """
253        Create a NoValidator instance from a directory path.
254
255        This factory method implements the DataValidator protocol's required
256        interface for directory-based instantiation. For NoValidator, the path
257        parameter is ignored because no configuration is needed. This method
258        exists purely to satisfy the protocol requirement.
259
260        The method simply delegates to the constructor, which creates a
261        stateless NoValidator instance. The returned validator will pass all
262        data through unchanged regardless of the provided path.
263
264        Parameters
265        ----------
266        path : str or pathlib.Path
267            Path to a configuration directory. This parameter is ignored for
268            NoValidator since no configuration is required. It exists only to
269            maintain interface compatibility with the DataValidator protocol.
270
271        Returns
272        -------
273        NoValidator
274            A new NoValidator instance that will return all data unchanged.
275
276        Warns
277        -----
278        UserWarning
279            Issued during instantiation (via ``__init__``) warning that
280            validation is disabled.
281
282        See Also
283        --------
284        __init__ : Constructor that creates the NoValidator instance.
285        validate : Method that returns data unchanged.
286        adc_toolkit.data.abs.DataValidator : Protocol defining this interface.
287
288        Notes
289        -----
290        Unlike actual validator implementations (GXValidator, PanderaValidator),
291        NoValidator does not read any configuration files from the provided
292        directory. The path parameter is accepted and ignored to maintain
293        protocol compatibility.
294
295        This design allows NoValidator to be used as a drop-in replacement for
296        other validators without changing the calling code's interface.
297
298        The ``# noqa: ARG003`` comment suppresses linting warnings about the
299        unused ``path`` parameter, which is intentionally unused.
300
301        Examples
302        --------
303        Creating a NoValidator using the factory method:
304
305        >>> from adc_toolkit.data.validators.no_validator import NoValidator
306        >>> validator = NoValidator.in_directory("/path/to/config")
307        UserWarning: Not using any validator is not recommended...
308        >>> # Path is ignored
309
310        The path parameter has no effect on behavior:
311
312        >>> validator1 = NoValidator.in_directory("/some/path")
313        >>> validator2 = NoValidator.in_directory("/different/path")
314        >>> # Both validators behave identically
315
316        Using with ValidatedDataCatalog's factory method:
317
318        >>> from adc_toolkit.data import ValidatedDataCatalog
319        >>> # If config directory contains NoValidator configuration
320        >>> catalog = ValidatedDataCatalog.in_directory("config/")
321        >>> # Internally calls NoValidator.in_directory()
322
323        Drop-in replacement for other validators:
324
325        >>> # Switch from GXValidator to NoValidator without code changes
326        >>> # Before:
327        >>> # validator = GXValidator.in_directory("validations/")
328        >>> # After (for testing):
329        >>> validator = NoValidator.in_directory("validations/")
330        >>> # Same interface, no validation performed
331        """
332        return cls()
333
334    def validate(self, name: str, data: Data) -> Data:  # noqa: ARG002
335        """
336        Return data unchanged without performing any validation.
337
338        This method implements the DataValidator protocol's validate interface
339        as a no-operation (no-op) pass-through. It accepts a dataset and
340        immediately returns it without performing any validation checks, schema
341        verification, or data quality assessments.
342
343        Unlike actual validator implementations, this method does not check
344        column names, data types, value ranges, null constraints, or any other
345        validation rules. The returned data is the exact same object passed as
346        input, with no modifications or metadata additions.
347
348        Parameters
349        ----------
350        name : str
351            The name identifying the dataset being validated. For NoValidator,
352            this parameter is ignored since no validation is performed. It
353            exists only to maintain interface compatibility with the
354            DataValidator protocol.
355        data : Data
356            The dataset to validate (or rather, to pass through unchanged).
357            Must be a Data protocol-compatible object such as pandas.DataFrame,
358            pyspark.sql.DataFrame, or any object with ``columns`` and ``dtypes``
359            properties.
360
361        Returns
362        -------
363        Data
364            The exact same data object that was passed as input, with no
365            modifications, transformations, or validation metadata attached.
366            The returned value is identical (``is`` relationship) to the input.
367
368        Raises
369        ------
370        None
371            This method never raises validation-related exceptions. It is
372            guaranteed to return the input data unchanged.
373
374        See Also
375        --------
376        __init__ : Constructor that creates the NoValidator instance.
377        in_directory : Factory method for instantiation.
378        adc_toolkit.data.abs.DataValidator.validate : Protocol method definition.
379
380        Notes
381        -----
382        **No-op behavior:**
383
384        This method is intentionally a no-operation. It does not:
385
386        - Check schema (column names, data types, structure)
387        - Validate constraints (null checks, uniqueness, ranges)
388        - Verify statistical properties (distributions, outliers)
389        - Execute business rules or custom validation logic
390        - Log validation results or maintain audit trails
391        - Modify or transform the data in any way
392        - Attach validation metadata to the returned data
393
394        **Identity preservation:**
395
396        The returned data is the exact same object reference as the input:
397
398        >>> result = validator.validate("name", data)
399        >>> result is data  # Always True
400
401        **Parameter usage:**
402
403        The ``name`` parameter is accepted but ignored (hence ``# noqa: ARG002``).
404        In actual validators, this parameter identifies which validation suite
405        to execute. For NoValidator, it has no effect on behavior.
406
407        **Thread safety:**
408
409        Since this method maintains no state and performs no I/O, it is
410        inherently thread-safe. Multiple threads can call validate
411        concurrently without synchronization.
412
413        **Performance:**
414
415        This method has O(1) time complexity and negligible overhead, making
416        it suitable for performance-critical scenarios where validation is
417        bypassed.
418
419        Examples
420        --------
421        Basic validation (no-op) with pandas DataFrame:
422
423        >>> import pandas as pd
424        >>> from adc_toolkit.data.validators.no_validator import NoValidator
425        >>> validator = NoValidator()
426        >>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
427        >>> result = validator.validate("my_dataset", df)
428        >>> result is df
429        True
430        >>> # Data passes through completely unchanged
431
432        The name parameter has no effect:
433
434        >>> result1 = validator.validate("dataset_1", df)
435        >>> result2 = validator.validate("dataset_2", df)
436        >>> result1 is df and result2 is df
437        True
438
439        No validation means invalid data passes through:
440
441        >>> invalid_df = pd.DataFrame({"x": [None, None, None]})
442        >>> # In real validator, this might fail null checks
443        >>> result = validator.validate("strict_schema", invalid_df)
444        >>> result is invalid_df  # Passes through anyway
445        True
446
447        Integration with ValidatedDataCatalog:
448
449        >>> from adc_toolkit.data import ValidatedDataCatalog
450        >>> catalog = ValidatedDataCatalog(catalog=my_catalog, validator=NoValidator())
451        >>> # Load data without validation
452        >>> df = catalog.load("dataset_name")
453        >>> # Save data without validation
454        >>> catalog.save("output_name", df)
455
456        Using in a data pipeline (bypass validation during development):
457
458        >>> def pipeline(validator: DataValidator) -> None:
459        ...     raw = load_raw_data()
460        ...     validated_raw = validator.validate("raw", raw)
461        ...     processed = transform(validated_raw)
462        ...     validated_processed = validator.validate("processed", processed)
463        ...     save(validated_processed)
464        >>> # Development: use NoValidator to skip validation
465        >>> pipeline(NoValidator())
466        >>> # Production: use actual validator
467        >>> # pipeline(GXValidator.in_directory("validations/"))
468        """
469        return data

A no-operation validator that passes data through without validation.

NoValidator implements the DataValidator protocol but performs no actual validation. It returns all data unchanged, making it a pass-through or no-op validator. This is useful in scenarios where validation is not required, such as during development, testing, or when working with pre-validated or trusted data sources.

The validator emits a UserWarning upon instantiation to alert developers that validation is disabled, helping prevent accidental use in production environments where data quality assurance is critical.

Attributes
  • None: This class maintains no internal state.
Methods

validate(name, data) Return data unchanged without performing any validation. in_directory(path) Create a NoValidator instance, ignoring the provided path.

See Also

adc_toolkit.data.abs.DataValidator: Protocol defining validator interface.
adc_toolkit.data.validators.gx.GXValidator: Validator using Great Expectations.
adc_toolkit.data.validators.pandera.PanderaValidator: Validator using Pandera.
adc_toolkit.data.ValidatedDataCatalog: Catalog that uses validators.

Notes

This validator is intentionally minimal and does not maintain any configuration, validation rules, or state. It exists solely to satisfy the DataValidator protocol while bypassing validation logic.

When to use NoValidator:

  • Development and prototyping: Quickly iterate on data pipelines without validation overhead slowing down the development cycle.
  • Testing: Unit tests where validation logic is mocked, not relevant, or tested separately.
  • Trusted data sources: Data from sources with external validation guarantees (e.g., validated by another system before ingestion).
  • Performance optimization: Temporary bypass when validation becomes a computational bottleneck and data quality is assured through other means.
  • Debugging: Isolate issues by removing validation from the pipeline.

When NOT to use NoValidator:

  • Production data pipelines where data quality is critical
  • User-facing applications where invalid data could cause errors
  • Scenarios where schema drift or data corruption must be detected
  • Compliance-driven contexts requiring validation audit trails

Protocol conformance:

NoValidator satisfies the DataValidator protocol by implementing:

  • validate(name: str, data: Data) -> Data: Returns data unchanged
  • in_directory(path: str | Path) -> DataValidator: Factory method

The class uses structural subtyping (PEP 544) to conform to the protocol without explicit inheritance.

Warnings

UserWarning Issued on instantiation to warn that validation is disabled.

Examples

Basic instantiation and usage:

>>> import pandas as pd
>>> from adc_toolkit.data.validators.no_validator import NoValidator
>>> validator = NoValidator()
UserWarning: Not using any validator is not recommended...
>>> df = pd.DataFrame({"x": [1, 2, 3], "y": [4, 5, 6]})
>>> result = validator.validate("dataset_name", df)
>>> result is df  # Same object returned
True

Using the factory method:

>>> validator = NoValidator.in_directory("/config/path")
>>> # Path is ignored; still returns NoValidator instance

Integration with ValidatedDataCatalog:

>>> from adc_toolkit.data import ValidatedDataCatalog
>>> from adc_toolkit.data.catalogs.kedro import KedroDataCatalog
>>> catalog = KedroDataCatalog.in_directory("config/")
>>> validator = NoValidator()
>>> validated_catalog = ValidatedDataCatalog(catalog=catalog, validator=validator)
>>> # All data passes through without validation

Testing scenario where validation is not needed:

>>> def test_data_transformation():
...     # Use NoValidator to focus test on transformation logic
...     validator = NoValidator()
...     input_data = create_test_data()
...     validated = validator.validate("test", input_data)
...     result = transform(validated)
...     assert result.shape == expected_shape
NoValidator()
182    def __init__(self) -> None:
183        """
184        Initialize the NoValidator instance.
185
186        Creates a new NoValidator that will pass all data through unchanged.
187        Upon instantiation, a UserWarning is emitted to alert developers that
188        validation is disabled. This warning helps prevent accidental use in
189        production environments where data quality assurance is critical.
190
191        Parameters
192        ----------
193        None
194
195        Returns
196        -------
197        None
198
199        Warns
200        -----
201        UserWarning
202            Always emitted on instantiation, warning that no validation will
203            be performed and recommending the use of an actual validator from
204            the `adc_toolkit.data.validators` module.
205
206        See Also
207        --------
208        in_directory : Factory method for creating NoValidator instances.
209        validate : Method that returns data unchanged.
210
211        Notes
212        -----
213        The warning is emitted with ``stacklevel=2`` to ensure it points to
214        the caller's location rather than this constructor, making it easier
215        to identify where the NoValidator is being instantiated.
216
217        This constructor takes no parameters and maintains no internal state,
218        making all NoValidator instances functionally equivalent.
219
220        Examples
221        --------
222        Instantiating the validator triggers a warning:
223
224        >>> from adc_toolkit.data.validators.no_validator import NoValidator
225        >>> validator = NoValidator()
226        UserWarning: Not using any validator is not recommended. Consider using
227        a validator from the `adc_toolkit.data.validators` module.
228
229        The warning can be suppressed if desired (though not recommended):
230
231        >>> import warnings
232        >>> with warnings.catch_warnings():
233        ...     warnings.simplefilter("ignore", UserWarning)
234        ...     validator = NoValidator()
235        >>> # No warning emitted
236
237        Multiple instances are functionally identical:
238
239        >>> validator1 = NoValidator()
240        >>> validator2 = NoValidator()
241        >>> # Both behave identically
242        """
243        warnings.warn(
244            "Not using any validator is not recommended. "
245            "Consider using a validator from the `adc_toolkit.data.validators` module.",
246            UserWarning,
247            stacklevel=2,
248        )

Initialize the NoValidator instance.

Creates a new NoValidator that will pass all data through unchanged. Upon instantiation, a UserWarning is emitted to alert developers that validation is disabled. This warning helps prevent accidental use in production environments where data quality assurance is critical.

Parameters
  • None
Returns
  • None
Warns
  • UserWarning: Always emitted on instantiation, warning that no validation will be performed and recommending the use of an actual validator from the adc_toolkit.data.validators module.
See Also

in_directory: Factory method for creating NoValidator instances.
validate: Method that returns data unchanged.

Notes

The warning is emitted with stacklevel=2 to ensure it points to the caller's location rather than this constructor, making it easier to identify where the NoValidator is being instantiated.

This constructor takes no parameters and maintains no internal state, making all NoValidator instances functionally equivalent.

Examples

Instantiating the validator triggers a warning:

>>> from adc_toolkit.data.validators.no_validator import NoValidator
>>> validator = NoValidator()
UserWarning: Not using any validator is not recommended. Consider using
a validator from the `adc_toolkit.data.validators` module.

The warning can be suppressed if desired (though not recommended):

>>> import warnings
>>> with warnings.catch_warnings():
...     warnings.simplefilter("ignore", UserWarning)
...     validator = NoValidator()
>>> # No warning emitted

Multiple instances are functionally identical:

>>> validator1 = NoValidator()
>>> validator2 = NoValidator()
>>> # Both behave identically
@classmethod
def in_directory( cls, path: str | pathlib.Path) -> NoValidator:
250    @classmethod
251    def in_directory(cls, path: str | Path) -> "NoValidator":  # noqa: ARG003
252        """
253        Create a NoValidator instance from a directory path.
254
255        This factory method implements the DataValidator protocol's required
256        interface for directory-based instantiation. For NoValidator, the path
257        parameter is ignored because no configuration is needed. This method
258        exists purely to satisfy the protocol requirement.
259
260        The method simply delegates to the constructor, which creates a
261        stateless NoValidator instance. The returned validator will pass all
262        data through unchanged regardless of the provided path.
263
264        Parameters
265        ----------
266        path : str or pathlib.Path
267            Path to a configuration directory. This parameter is ignored for
268            NoValidator since no configuration is required. It exists only to
269            maintain interface compatibility with the DataValidator protocol.
270
271        Returns
272        -------
273        NoValidator
274            A new NoValidator instance that will return all data unchanged.
275
276        Warns
277        -----
278        UserWarning
279            Issued during instantiation (via ``__init__``) warning that
280            validation is disabled.
281
282        See Also
283        --------
284        __init__ : Constructor that creates the NoValidator instance.
285        validate : Method that returns data unchanged.
286        adc_toolkit.data.abs.DataValidator : Protocol defining this interface.
287
288        Notes
289        -----
290        Unlike actual validator implementations (GXValidator, PanderaValidator),
291        NoValidator does not read any configuration files from the provided
292        directory. The path parameter is accepted and ignored to maintain
293        protocol compatibility.
294
295        This design allows NoValidator to be used as a drop-in replacement for
296        other validators without changing the calling code's interface.
297
298        The ``# noqa: ARG003`` comment suppresses linting warnings about the
299        unused ``path`` parameter, which is intentionally unused.
300
301        Examples
302        --------
303        Creating a NoValidator using the factory method:
304
305        >>> from adc_toolkit.data.validators.no_validator import NoValidator
306        >>> validator = NoValidator.in_directory("/path/to/config")
307        UserWarning: Not using any validator is not recommended...
308        >>> # Path is ignored
309
310        The path parameter has no effect on behavior:
311
312        >>> validator1 = NoValidator.in_directory("/some/path")
313        >>> validator2 = NoValidator.in_directory("/different/path")
314        >>> # Both validators behave identically
315
316        Using with ValidatedDataCatalog's factory method:
317
318        >>> from adc_toolkit.data import ValidatedDataCatalog
319        >>> # If config directory contains NoValidator configuration
320        >>> catalog = ValidatedDataCatalog.in_directory("config/")
321        >>> # Internally calls NoValidator.in_directory()
322
323        Drop-in replacement for other validators:
324
325        >>> # Switch from GXValidator to NoValidator without code changes
326        >>> # Before:
327        >>> # validator = GXValidator.in_directory("validations/")
328        >>> # After (for testing):
329        >>> validator = NoValidator.in_directory("validations/")
330        >>> # Same interface, no validation performed
331        """
332        return cls()

Create a NoValidator instance from a directory path.

This factory method implements the DataValidator protocol's required interface for directory-based instantiation. For NoValidator, the path parameter is ignored because no configuration is needed. This method exists purely to satisfy the protocol requirement.

The method simply delegates to the constructor, which creates a stateless NoValidator instance. The returned validator will pass all data through unchanged regardless of the provided path.

Parameters
  • path (str or pathlib.Path): Path to a configuration directory. This parameter is ignored for NoValidator since no configuration is required. It exists only to maintain interface compatibility with the DataValidator protocol.
Returns
  • NoValidator: A new NoValidator instance that will return all data unchanged.
Warns
  • UserWarning: Issued during instantiation (via __init__) warning that validation is disabled.
See Also

__init__: Constructor that creates the NoValidator instance.
validate: Method that returns data unchanged.
adc_toolkit.data.abs.DataValidator: Protocol defining this interface.

Notes

Unlike actual validator implementations (GXValidator, PanderaValidator), NoValidator does not read any configuration files from the provided directory. The path parameter is accepted and ignored to maintain protocol compatibility.

This design allows NoValidator to be used as a drop-in replacement for other validators without changing the calling code's interface.

The # noqa: ARG003 comment suppresses linting warnings about the unused path parameter, which is intentionally unused.

Examples

Creating a NoValidator using the factory method:

>>> from adc_toolkit.data.validators.no_validator import NoValidator
>>> validator = NoValidator.in_directory("/path/to/config")
UserWarning: Not using any validator is not recommended...
>>> # Path is ignored

The path parameter has no effect on behavior:

>>> validator1 = NoValidator.in_directory("/some/path")
>>> validator2 = NoValidator.in_directory("/different/path")
>>> # Both validators behave identically

Using with ValidatedDataCatalog's factory method:

>>> from adc_toolkit.data import ValidatedDataCatalog
>>> # If config directory contains NoValidator configuration
>>> catalog = ValidatedDataCatalog.in_directory("config/")
>>> # Internally calls NoValidator.in_directory()

Drop-in replacement for other validators:

>>> # Switch from GXValidator to NoValidator without code changes
>>> # Before:
>>> # validator = GXValidator.in_directory("validations/")
>>> # After (for testing):
>>> validator = NoValidator.in_directory("validations/")
>>> # Same interface, no validation performed
def validate( self, name: str, data: adc_toolkit.data.abs.Data) -> adc_toolkit.data.abs.Data:
334    def validate(self, name: str, data: Data) -> Data:  # noqa: ARG002
335        """
336        Return data unchanged without performing any validation.
337
338        This method implements the DataValidator protocol's validate interface
339        as a no-operation (no-op) pass-through. It accepts a dataset and
340        immediately returns it without performing any validation checks, schema
341        verification, or data quality assessments.
342
343        Unlike actual validator implementations, this method does not check
344        column names, data types, value ranges, null constraints, or any other
345        validation rules. The returned data is the exact same object passed as
346        input, with no modifications or metadata additions.
347
348        Parameters
349        ----------
350        name : str
351            The name identifying the dataset being validated. For NoValidator,
352            this parameter is ignored since no validation is performed. It
353            exists only to maintain interface compatibility with the
354            DataValidator protocol.
355        data : Data
356            The dataset to validate (or rather, to pass through unchanged).
357            Must be a Data protocol-compatible object such as pandas.DataFrame,
358            pyspark.sql.DataFrame, or any object with ``columns`` and ``dtypes``
359            properties.
360
361        Returns
362        -------
363        Data
364            The exact same data object that was passed as input, with no
365            modifications, transformations, or validation metadata attached.
366            The returned value is identical (``is`` relationship) to the input.
367
368        Raises
369        ------
370        None
371            This method never raises validation-related exceptions. It is
372            guaranteed to return the input data unchanged.
373
374        See Also
375        --------
376        __init__ : Constructor that creates the NoValidator instance.
377        in_directory : Factory method for instantiation.
378        adc_toolkit.data.abs.DataValidator.validate : Protocol method definition.
379
380        Notes
381        -----
382        **No-op behavior:**
383
384        This method is intentionally a no-operation. It does not:
385
386        - Check schema (column names, data types, structure)
387        - Validate constraints (null checks, uniqueness, ranges)
388        - Verify statistical properties (distributions, outliers)
389        - Execute business rules or custom validation logic
390        - Log validation results or maintain audit trails
391        - Modify or transform the data in any way
392        - Attach validation metadata to the returned data
393
394        **Identity preservation:**
395
396        The returned data is the exact same object reference as the input:
397
398        >>> result = validator.validate("name", data)
399        >>> result is data  # Always True
400
401        **Parameter usage:**
402
403        The ``name`` parameter is accepted but ignored (hence ``# noqa: ARG002``).
404        In actual validators, this parameter identifies which validation suite
405        to execute. For NoValidator, it has no effect on behavior.
406
407        **Thread safety:**
408
409        Since this method maintains no state and performs no I/O, it is
410        inherently thread-safe. Multiple threads can call validate
411        concurrently without synchronization.
412
413        **Performance:**
414
415        This method has O(1) time complexity and negligible overhead, making
416        it suitable for performance-critical scenarios where validation is
417        bypassed.
418
419        Examples
420        --------
421        Basic validation (no-op) with pandas DataFrame:
422
423        >>> import pandas as pd
424        >>> from adc_toolkit.data.validators.no_validator import NoValidator
425        >>> validator = NoValidator()
426        >>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
427        >>> result = validator.validate("my_dataset", df)
428        >>> result is df
429        True
430        >>> # Data passes through completely unchanged
431
432        The name parameter has no effect:
433
434        >>> result1 = validator.validate("dataset_1", df)
435        >>> result2 = validator.validate("dataset_2", df)
436        >>> result1 is df and result2 is df
437        True
438
439        No validation means invalid data passes through:
440
441        >>> invalid_df = pd.DataFrame({"x": [None, None, None]})
442        >>> # In real validator, this might fail null checks
443        >>> result = validator.validate("strict_schema", invalid_df)
444        >>> result is invalid_df  # Passes through anyway
445        True
446
447        Integration with ValidatedDataCatalog:
448
449        >>> from adc_toolkit.data import ValidatedDataCatalog
450        >>> catalog = ValidatedDataCatalog(catalog=my_catalog, validator=NoValidator())
451        >>> # Load data without validation
452        >>> df = catalog.load("dataset_name")
453        >>> # Save data without validation
454        >>> catalog.save("output_name", df)
455
456        Using in a data pipeline (bypass validation during development):
457
458        >>> def pipeline(validator: DataValidator) -> None:
459        ...     raw = load_raw_data()
460        ...     validated_raw = validator.validate("raw", raw)
461        ...     processed = transform(validated_raw)
462        ...     validated_processed = validator.validate("processed", processed)
463        ...     save(validated_processed)
464        >>> # Development: use NoValidator to skip validation
465        >>> pipeline(NoValidator())
466        >>> # Production: use actual validator
467        >>> # pipeline(GXValidator.in_directory("validations/"))
468        """
469        return data

Return data unchanged without performing any validation.

This method implements the DataValidator protocol's validate interface as a no-operation (no-op) pass-through. It accepts a dataset and immediately returns it without performing any validation checks, schema verification, or data quality assessments.

Unlike actual validator implementations, this method does not check column names, data types, value ranges, null constraints, or any other validation rules. The returned data is the exact same object passed as input, with no modifications or metadata additions.

Parameters
  • name (str): The name identifying the dataset being validated. For NoValidator, this parameter is ignored since no validation is performed. It exists only to maintain interface compatibility with the DataValidator protocol.
  • data (Data): The dataset to validate (or rather, to pass through unchanged). Must be a Data protocol-compatible object such as pandas.DataFrame, pyspark.sql.DataFrame, or any object with columns and dtypes properties.
Returns
  • Data: The exact same data object that was passed as input, with no modifications, transformations, or validation metadata attached. The returned value is identical (is relationship) to the input.
Raises
  • None: This method never raises validation-related exceptions. It is guaranteed to return the input data unchanged.
See Also

__init__: Constructor that creates the NoValidator instance.
in_directory: Factory method for instantiation.
adc_toolkit.data.abs.DataValidator.validate: Protocol method definition.

Notes

No-op behavior:

This method is intentionally a no-operation. It does not:

  • Check schema (column names, data types, structure)
  • Validate constraints (null checks, uniqueness, ranges)
  • Verify statistical properties (distributions, outliers)
  • Execute business rules or custom validation logic
  • Log validation results or maintain audit trails
  • Modify or transform the data in any way
  • Attach validation metadata to the returned data

Identity preservation:

The returned data is the exact same object reference as the input:

>>> result = validator.validate("name", data)
>>> result is data  # Always True

Parameter usage:

The name parameter is accepted but ignored (hence # noqa: ARG002). In actual validators, this parameter identifies which validation suite to execute. For NoValidator, it has no effect on behavior.

Thread safety:

Since this method maintains no state and performs no I/O, it is inherently thread-safe. Multiple threads can call validate concurrently without synchronization.

Performance:

This method has O(1) time complexity and negligible overhead, making it suitable for performance-critical scenarios where validation is bypassed.

Examples

Basic validation (no-op) with pandas DataFrame:

>>> import pandas as pd
>>> from adc_toolkit.data.validators.no_validator import NoValidator
>>> validator = NoValidator()
>>> df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
>>> result = validator.validate("my_dataset", df)
>>> result is df
True
>>> # Data passes through completely unchanged

The name parameter has no effect:

>>> result1 = validator.validate("dataset_1", df)
>>> result2 = validator.validate("dataset_2", df)
>>> result1 is df and result2 is df
True

No validation means invalid data passes through:

>>> invalid_df = pd.DataFrame({"x": [None, None, None]})
>>> # In real validator, this might fail null checks
>>> result = validator.validate("strict_schema", invalid_df)
>>> result is invalid_df  # Passes through anyway
True

Integration with ValidatedDataCatalog:

>>> from adc_toolkit.data import ValidatedDataCatalog
>>> catalog = ValidatedDataCatalog(catalog=my_catalog, validator=NoValidator())
>>> # Load data without validation
>>> df = catalog.load("dataset_name")
>>> # Save data without validation
>>> catalog.save("output_name", df)

Using in a data pipeline (bypass validation during development):

>>> def pipeline(validator: DataValidator) -> None:
...     raw = load_raw_data()
...     validated_raw = validator.validate("raw", raw)
...     processed = transform(validated_raw)
...     validated_processed = validator.validate("processed", processed)
...     save(validated_processed)
>>> # Development: use NoValidator to skip validation
>>> pipeline(NoValidator())
>>> # Production: use actual validator
>>> # pipeline(GXValidator.in_directory("validations/"))