diff --git a/noxfile.py b/noxfile.py index 0224d4379..88f1757c9 100644 --- a/noxfile.py +++ b/noxfile.py @@ -195,6 +195,12 @@ def install_extras( pandas_stubs: bool = True, ) -> None: """Install dependencies.""" + + if isinstance(session.virtualenv, nox.virtualenv.PassthroughEnv): + # skip this step if there's no virtual environment specified + session.run("pip", "install", "-e", ".", "--no-deps") + return + specs, pip_specs = [], [] pandas_version = "" if pandas == "latest" else f"=={pandas}" for spec in REQUIRES[extra].values(): diff --git a/pandera/typing/config.py b/pandera/typing/config.py index 4371e3afa..d722bc333 100644 --- a/pandera/typing/config.py +++ b/pandera/typing/config.py @@ -34,6 +34,8 @@ class BaseConfig: # pylint:disable=R0903 #: coerce types of all MultiIndex components multiindex_coerce: bool = False + #: make sure the MultiIndex is unique along the list of columns + multiindex_unique = None #: make sure all specified columns are in validated MultiIndex - #: if ``"filter"``, removes indexes not specified in the schema multiindex_strict: StrictType = False diff --git a/tests/core/test_model.py b/tests/core/test_model.py index 9291e384f..e69d535fb 100644 --- a/tests/core/test_model.py +++ b/tests/core/test_model.py @@ -725,6 +725,40 @@ class Config: assert expected == Child.to_schema() +def test_multiindex_unique() -> None: + class Base(pa.SchemaModel): + a: Series[int] + idx_1: Index[str] + idx_2: Index[str] + + class Config: + name = "Base schema" + coerce = True + ordered = True + multiindex_coerce = True + multiindex_strict = True + multiindex_unique = ["idx_1", "idx_2"] + multiindex_name: Optional[str] = "mi" + unique_column_names = True + + expected = pa.DataFrameSchema( + columns={"a": pa.Column(int)}, + index=pa.MultiIndex( + [pa.Index(str, name="idx_1"), pa.Index(str, name="idx_2")], + coerce=True, + strict=True, + name="mi", + unique=["idx_1", "idx_2"], + ), + name="Base schema", + coerce=True, + ordered=True, + unique_column_names=True, + ) + + assert expected == Base.to_schema() + + def test_config_docstrings() -> None: class Model(pa.SchemaModel): """foo"""