Skip to content

Commit 2e355f7

Browse files
Add unit test suite for Ibis components, fix a bug (#2065)
* Run `pre-commit` on all files to fix linter issues Signed-off-by: Deepyaman Datta <[email protected]> * Implement `regex` option and add additional checks Signed-off-by: Deepyaman Datta <[email protected]> * Support validating set of columns matching a regex Signed-off-by: Deepyaman Datta <[email protected]> * Implement binary and boolean types (and test them) Signed-off-by: Deepyaman Datta <[email protected]> * Add unit test suite for Ibis components, fix a bug Signed-off-by: Deepyaman Datta <[email protected]> --------- Signed-off-by: Deepyaman Datta <[email protected]> Co-authored-by: Niels Bantilan <[email protected]>
1 parent dcd9752 commit 2e355f7

File tree

3 files changed

+388
-48
lines changed

3 files changed

+388
-48
lines changed

pandera/backends/ibis/components.py

Lines changed: 64 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import warnings
56
from typing import TYPE_CHECKING, Iterable, List, Optional, cast
67

78
import ibis
@@ -12,7 +13,12 @@
1213
from pandera.backends.ibis.base import IbisSchemaBackend
1314
from pandera.config import ValidationScope
1415
from pandera.engines.ibis_engine import Engine
15-
from pandera.errors import SchemaError, SchemaErrorReason, SchemaErrors
16+
from pandera.errors import (
17+
SchemaDefinitionError,
18+
SchemaError,
19+
SchemaErrorReason,
20+
SchemaErrors,
21+
)
1622
from pandera.validation_depth import validate_scope, validation_type
1723

1824
if TYPE_CHECKING:
@@ -37,59 +43,69 @@ def validate(
3743
"""Validation backend implementation for Ibis table columns."""
3844
error_handler = ErrorHandler(lazy)
3945

46+
if inplace:
47+
warnings.warn("setting inplace=True will have no effect.")
48+
49+
if schema.name is None:
50+
raise SchemaDefinitionError(
51+
"Column schema must have a name specified."
52+
)
53+
4054
def validate_column(check_obj, column_name):
4155
# make sure the schema component mutations are reverted after
4256
# validation
4357
_orig_name = schema.name
4458
_orig_regex = schema.regex
4559

46-
# set the column name and regex flag for a single column
47-
schema.name = column_name
48-
schema.regex = False
49-
50-
# TODO(deepyaman): subsample the check object if head, tail, or sample are specified
51-
sample = check_obj[column_name]
52-
53-
# run the checks
54-
core_checks = [
55-
self.check_dtype,
56-
self.run_checks,
57-
]
58-
59-
args = (sample, schema)
60-
for check in core_checks:
61-
results = check(*args)
62-
if isinstance(results, CoreCheckResult):
63-
results = [results]
64-
65-
for result in results:
66-
if result.passed:
67-
continue
68-
# Why cast `results` only in components.py, not in container.py?
69-
results = cast(List[CoreCheckResult], results)
70-
if result.schema_error is not None:
71-
error = result.schema_error
72-
else:
73-
error = SchemaError(
74-
schema=schema,
75-
data=check_obj,
76-
message=result.message,
77-
failure_cases=result.failure_cases,
78-
check=result.check,
79-
check_index=result.check_index,
80-
check_output=result.check_output,
81-
reason_code=result.reason_code,
82-
)
83-
error_handler.collect_error( # Why indent (unlike in container.py)?
84-
validation_type(result.reason_code),
85-
result.reason_code,
86-
error,
87-
original_exc=result.original_exc,
88-
)
89-
90-
# revert the schema component mutations
91-
schema.name = _orig_name
92-
schema.regex = _orig_regex
60+
try:
61+
# set the column name and regex flag for a single column
62+
schema.name = column_name
63+
schema.regex = False
64+
65+
# TODO(deepyaman): subsample the check object if head, tail, or sample are specified
66+
sample = check_obj[column_name]
67+
68+
# run the checks
69+
core_checks = [
70+
self.check_dtype,
71+
self.run_checks,
72+
]
73+
74+
args = (sample, schema)
75+
for check in core_checks:
76+
results = check(*args)
77+
if isinstance(results, CoreCheckResult):
78+
results = [results]
79+
80+
for result in results:
81+
if result.passed:
82+
continue
83+
# Why cast `results` only in components.py, not in container.py?
84+
results = cast(List[CoreCheckResult], results)
85+
if result.schema_error is not None:
86+
error = result.schema_error
87+
else:
88+
error = SchemaError(
89+
schema=schema,
90+
data=check_obj,
91+
message=result.message,
92+
failure_cases=result.failure_cases,
93+
check=result.check,
94+
check_index=result.check_index,
95+
check_output=result.check_output,
96+
reason_code=result.reason_code,
97+
)
98+
error_handler.collect_error( # Why indent (unlike in container.py)?
99+
validation_type(result.reason_code),
100+
result.reason_code,
101+
error,
102+
original_exc=result.original_exc,
103+
)
104+
105+
finally:
106+
# revert the schema component mutations
107+
schema.name = _orig_name
108+
schema.regex = _orig_regex
93109

94110
column_keys_to_check = (
95111
self.get_regex_columns(schema, check_obj)

0 commit comments

Comments
 (0)