dataframely 2.12.0__tar.gz → 2.13.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dataframely-2.12.0 → dataframely-2.13.0}/PKG-INFO +1 -1
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/collection/collection.py +44 -6
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/filter_result.py +11 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/pyproject.toml +1 -1
- dataframely-2.13.0/tests/collection/test_skip_member_validation.py +108 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.claude/CLAUDE.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.copier-answers.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.envrc +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.gitattributes +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/CODEOWNERS +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/copilot-instructions.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/dependabot.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/instructions/tests.instructions.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/release-drafter.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/workflows/build.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/workflows/chore.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/workflows/ci.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/workflows/copilot-setup-steps.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/workflows/nightly.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/workflows/release-drafter.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.github/workflows/scorecard.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.gitignore +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.lefthook.yaml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.prettierignore +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.prettierrc +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/.readthedocs.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/AGENTS.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/Cargo.lock +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/Cargo.toml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/LICENSE +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/README.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/SECURITY.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/__init__.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_base_schema.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_compat.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_deprecation.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_filter.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_match_to_schema.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_native.pyi +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_plugin.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_polars.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_pydantic.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_rule.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_serialization.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_storage/__init__.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_storage/_base.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_storage/_exc.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_storage/_fsspec.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_storage/constants.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_storage/delta.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_storage/parquet.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/_typing.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/collection/__init__.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/collection/_base.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/collection/filter_result.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/__init__.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/_base.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/_mixins.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/_registry.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/_utils.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/any.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/array.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/binary.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/bool.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/categorical.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/datetime.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/decimal.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/enum.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/float.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/integer.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/list.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/object.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/string.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/columns/struct.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/config.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/exc.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/experimental/__init__.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/experimental/infer_schema.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/functional.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/py.typed +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/random.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/schema.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/testing/__init__.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/testing/const.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/testing/factory.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/testing/mask.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/testing/rules.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/dataframely/testing/storage.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docker-compose.yml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/_static/custom.css +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/_static/favicon.ico +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/_templates/autosummary/class.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/_templates/autosummary/method.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/_templates/classes/column.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/_templates/classes/error.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/_templates/classes/filter_result.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/collection/generation.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/collection/index.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/collection/io.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/collection/metadata.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/collection/operations.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/collection/validation.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/columns/index.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/errors/index.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/experimental/index.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/filter_result/failure_info.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/filter_result/index.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/index.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/misc/index.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/schema/conversion.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/schema/generation.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/schema/index.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/schema/io.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/schema/metadata.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/api/schema/validation.rst +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/conf.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/css/custom.css +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/coding-agents.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/development.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/examples/index.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/examples/real-world.ipynb +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/faq.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/features/column-metadata.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/features/data-generation.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/features/index.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/features/lazy-validation.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/features/primary-keys.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/features/serialization.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/features/sql-generation.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/index.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/migration/index.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/migration/v1-v2.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/guides/quickstart.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/docs/index.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/pixi.lock +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/pixi.toml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/rust-toolchain.toml +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/skills/SKILL.md +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/src/lib.rs +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/src/polars_plugin/mod.rs +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/src/polars_plugin/rule_failure.rs +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/src/polars_plugin/utils.rs +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/src/polars_plugin/validation_error.rs +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/src/regex/errdefs.rs +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/src/regex/mod.rs +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/src/regex/repr.rs +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/benches/conftest.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/benches/test_collection.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/benches/test_failure.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/benches/test_schema.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_base.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_cast.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_collection_future_annotations.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_create_empty.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_dataframe_members.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_filter_one_to_n.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_filter_validate.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_ignore_in_filter.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_implementation.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_join.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_matches.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_optional_members.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_pipe.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_propagate_row_failures.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_repr.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_sample.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_serialization.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_storage.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_validate_input.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/__init__.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_any.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_array.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_binary.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_datetime.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_decimal.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_enum.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_float.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_integer.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_list.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_object.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_string.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/column_types/test_struct.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/__init__.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_alias.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_base.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_check.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_default_dtypes.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_description.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_matches.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_metadata.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_polars_schema.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_pyarrow.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_pydantic.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_rules.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_sample.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_sqlalchemy_columns.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_str.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/columns/test_utils.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/conftest.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/core_validation/__init__.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/core_validation/test_match_to_schema.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/core_validation/test_rule_evaluation.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/experimental/test_infer_schema.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/failure_info/test_storage.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/functional/test_concat.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/functional/test_relationships.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_base.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_cast.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_create_empty.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_create_empty_if_none.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_filter.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_inheritance.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_matches.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_pydantic_model.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_read_write_parquet.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_repr.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_rule_implementation.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_sample.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_serialization.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_storage.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/schema/test_validate.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/storage/test_delta.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/storage/test_fsspec.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/test_compat.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/test_config.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/test_deprecation.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/test_factory.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/test_native_regex.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/test_pydantic.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/test_random.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/test_serialization.py +0 -0
- {dataframely-2.12.0 → dataframely-2.13.0}/tests/test_typing.py +0 -0
|
@@ -386,6 +386,7 @@ class Collection(BaseCollection, ABC):
|
|
|
386
386
|
*,
|
|
387
387
|
cast: bool = False,
|
|
388
388
|
eager: bool = True,
|
|
389
|
+
skip_member_validation: bool = False,
|
|
389
390
|
**kwargs: Any,
|
|
390
391
|
) -> Self:
|
|
391
392
|
"""Validate that a set of data frames satisfy the collection's invariants.
|
|
@@ -406,6 +407,11 @@ class Collection(BaseCollection, ABC):
|
|
|
406
407
|
:meth:`~polars.LazyFrame.collect` on the individual member or
|
|
407
408
|
:meth:`collect_all` on the collection. Note that, in the latter case,
|
|
408
409
|
information from error messages is limited.
|
|
410
|
+
skip_member_validation: Whether to skip validating individual members and only
|
|
411
|
+
apply the collection filters. **Use this option with caution** as it
|
|
412
|
+
requires the caller to ensure that the individual members have been
|
|
413
|
+
validated. This option is particularly useful in performance-critical
|
|
414
|
+
scenarios where the members are known to be valid.
|
|
409
415
|
kwargs: Keyword arguments passed directly to :meth:`polars.collect_all` and
|
|
410
416
|
:meth:`polars.LazyFrame.collect` when `eager=True`.
|
|
411
417
|
|
|
@@ -429,7 +435,13 @@ class Collection(BaseCollection, ABC):
|
|
|
429
435
|
if eager:
|
|
430
436
|
# If we perform the validation eagerly, we call filter and check the failure
|
|
431
437
|
# information to properly construct a useful error message.
|
|
432
|
-
filtered, failures = cls.filter(
|
|
438
|
+
filtered, failures = cls.filter(
|
|
439
|
+
data,
|
|
440
|
+
cast=cast,
|
|
441
|
+
eager=True,
|
|
442
|
+
skip_member_validation=skip_member_validation,
|
|
443
|
+
**kwargs,
|
|
444
|
+
)
|
|
433
445
|
if any(len(failure) > 0 for failure in failures.values()):
|
|
434
446
|
errors: dict[str, str] = {}
|
|
435
447
|
for member, failure in failures.items():
|
|
@@ -460,7 +472,17 @@ class Collection(BaseCollection, ABC):
|
|
|
460
472
|
# efficiently as we cannot easily propagate error messages from different
|
|
461
473
|
# members anyways.
|
|
462
474
|
members: dict[str, pl.LazyFrame] = {
|
|
463
|
-
name:
|
|
475
|
+
name: (
|
|
476
|
+
(
|
|
477
|
+
member.schema.cast(data[name].lazy())
|
|
478
|
+
if cast
|
|
479
|
+
else data[name].lazy()
|
|
480
|
+
)
|
|
481
|
+
if skip_member_validation
|
|
482
|
+
else member.schema.validate(
|
|
483
|
+
data[name].lazy(), cast=cast, eager=False
|
|
484
|
+
)
|
|
485
|
+
)
|
|
464
486
|
for name, member in cls.members().items()
|
|
465
487
|
if name in data
|
|
466
488
|
}
|
|
@@ -556,6 +578,7 @@ class Collection(BaseCollection, ABC):
|
|
|
556
578
|
*,
|
|
557
579
|
cast: bool = False,
|
|
558
580
|
eager: bool = True,
|
|
581
|
+
skip_member_validation: bool = False,
|
|
559
582
|
**kwargs: Any,
|
|
560
583
|
) -> CollectionFilterResult[Self]:
|
|
561
584
|
"""Filter the members data frame by their schemas and the collection's filters.
|
|
@@ -572,6 +595,11 @@ class Collection(BaseCollection, ABC):
|
|
|
572
595
|
eager: Whether the filter operation should be performed eagerly.
|
|
573
596
|
Note that until https://github.com/pola-rs/polars/pull/24129 is
|
|
574
597
|
released, eagerly filtering can provide significant speedups.
|
|
598
|
+
skip_member_validation: Whether to skip filtering individual members and only
|
|
599
|
+
apply the collection filters. **Use this option with caution** as it
|
|
600
|
+
requires the caller to ensure that the individual members have been
|
|
601
|
+
validated. This option is particularly useful in performance-critical
|
|
602
|
+
scenarios where the members are known to already be valid.
|
|
575
603
|
kwargs: Keyword arguments passed directly to :meth:`polars.collect_all` and
|
|
576
604
|
:meth:`polars.LazyFrame.collect` when `eager=True`.
|
|
577
605
|
|
|
@@ -615,10 +643,20 @@ class Collection(BaseCollection, ABC):
|
|
|
615
643
|
if member.is_optional and member_name not in data:
|
|
616
644
|
continue
|
|
617
645
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
646
|
+
if skip_member_validation:
|
|
647
|
+
results[member_name] = (
|
|
648
|
+
member.schema.cast(data[member_name].lazy())
|
|
649
|
+
if cast
|
|
650
|
+
else data[member_name].lazy()
|
|
651
|
+
)
|
|
652
|
+
failures[member_name] = FailureInfo._create_empty(
|
|
653
|
+
member.schema, with_casting_rules=cast
|
|
654
|
+
)
|
|
655
|
+
else:
|
|
656
|
+
member_result, failures[member_name] = member.schema.filter(
|
|
657
|
+
data[member_name].lazy(), cast=cast, eager=eager, **kwargs
|
|
658
|
+
)
|
|
659
|
+
results[member_name] = member_result.lazy()
|
|
622
660
|
|
|
623
661
|
# Once we've done that, we can apply the filters on this collection. To this end,
|
|
624
662
|
# we iterate over all filters and store the filter results.
|
|
@@ -106,6 +106,17 @@ class FailureInfo(Generic[S]):
|
|
|
106
106
|
self._rule_columns = rule_columns
|
|
107
107
|
self.schema = schema
|
|
108
108
|
|
|
109
|
+
@classmethod
|
|
110
|
+
def _create_empty(cls, schema: type[S], with_casting_rules: bool) -> FailureInfo[S]:
|
|
111
|
+
rules = schema._validation_rules(with_cast=with_casting_rules)
|
|
112
|
+
lf = pl.LazyFrame(
|
|
113
|
+
schema={
|
|
114
|
+
**schema.to_polars_schema(), # type: ignore
|
|
115
|
+
**{rule: pl.Boolean for rule in rules},
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
return cls(lf=lf, rule_columns=list(rules.keys()), schema=schema)
|
|
119
|
+
|
|
109
120
|
@cached_property
|
|
110
121
|
def _df(self) -> pl.DataFrame:
|
|
111
122
|
return self._lf.collect()
|
|
@@ -27,7 +27,7 @@ description = "A declarative, polars-native data frame validation library"
|
|
|
27
27
|
name = "dataframely"
|
|
28
28
|
readme = "README.md"
|
|
29
29
|
requires-python = ">=3.10"
|
|
30
|
-
version = "2.
|
|
30
|
+
version = "2.13.0"
|
|
31
31
|
|
|
32
32
|
[project.optional-dependencies]
|
|
33
33
|
deltalake = ["deltalake"]
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Copyright (c) QuantCo 2025-2026
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
3
|
+
|
|
4
|
+
import polars as pl
|
|
5
|
+
import polars.exceptions as plexc
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
import dataframely as dy
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FirstSchema(dy.Schema):
|
|
12
|
+
a = dy.Float64(min=5)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SecondSchema(dy.Schema):
|
|
16
|
+
a = dy.String()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Collection(dy.Collection):
|
|
20
|
+
first: dy.LazyFrame[FirstSchema]
|
|
21
|
+
second: dy.LazyFrame[SecondSchema]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@pytest.mark.parametrize("df_type", [pl.DataFrame, pl.LazyFrame])
|
|
25
|
+
def test_validate_skip_member_validation_eager(
|
|
26
|
+
df_type: type[pl.DataFrame] | type[pl.LazyFrame],
|
|
27
|
+
) -> None:
|
|
28
|
+
first = df_type({"a": [3, 4, 5]}) # NOTE: first two rows are violations
|
|
29
|
+
second = df_type({"a": ["1", "2", "3"]})
|
|
30
|
+
|
|
31
|
+
with pytest.raises(dy.exc.ValidationError):
|
|
32
|
+
Collection.validate({"first": first, "second": second}, cast=True) # type: ignore
|
|
33
|
+
|
|
34
|
+
Collection.validate(
|
|
35
|
+
{"first": first, "second": second}, # type: ignore
|
|
36
|
+
cast=True,
|
|
37
|
+
skip_member_validation=True,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@pytest.mark.parametrize("df_type", [pl.DataFrame, pl.LazyFrame])
|
|
42
|
+
def test_validate_skip_member_validation_lazy(
|
|
43
|
+
df_type: type[pl.DataFrame] | type[pl.LazyFrame],
|
|
44
|
+
) -> None:
|
|
45
|
+
first = df_type({"a": [3, 4, 5]}) # NOTE: first two rows are violations
|
|
46
|
+
second = df_type({"a": ["1", "2", "3"]})
|
|
47
|
+
|
|
48
|
+
with pytest.raises(plexc.ComputeError):
|
|
49
|
+
Collection.validate(
|
|
50
|
+
{"first": first, "second": second}, # type: ignore
|
|
51
|
+
cast=True,
|
|
52
|
+
eager=False,
|
|
53
|
+
).collect_all()
|
|
54
|
+
|
|
55
|
+
Collection.validate(
|
|
56
|
+
{"first": first, "second": second}, # type: ignore
|
|
57
|
+
cast=True,
|
|
58
|
+
skip_member_validation=True,
|
|
59
|
+
eager=False,
|
|
60
|
+
).collect_all()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@pytest.mark.parametrize("df_type", [pl.DataFrame, pl.LazyFrame])
|
|
64
|
+
def test_filter_skip_member_validation_eager(
|
|
65
|
+
df_type: type[pl.DataFrame] | type[pl.LazyFrame],
|
|
66
|
+
) -> None:
|
|
67
|
+
first = df_type({"a": [3, 4, 5]}) # NOTE: first two rows are violations
|
|
68
|
+
second = df_type({"a": ["1", "2", "3"]})
|
|
69
|
+
|
|
70
|
+
_, failure_info = Collection.filter(
|
|
71
|
+
{"first": first, "second": second}, # type: ignore
|
|
72
|
+
cast=True,
|
|
73
|
+
)
|
|
74
|
+
assert failure_info["first"].counts() == {"a|min": 2}
|
|
75
|
+
assert failure_info["second"].counts() == {}
|
|
76
|
+
|
|
77
|
+
_, failure_info = Collection.filter(
|
|
78
|
+
{"first": first, "second": second}, # type: ignore
|
|
79
|
+
cast=True,
|
|
80
|
+
skip_member_validation=True,
|
|
81
|
+
)
|
|
82
|
+
assert failure_info["first"].counts() == {}
|
|
83
|
+
assert failure_info["second"].counts() == {}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@pytest.mark.parametrize("df_type", [pl.DataFrame, pl.LazyFrame])
|
|
87
|
+
def test_filter_skip_member_validation_lazy(
|
|
88
|
+
df_type: type[pl.DataFrame] | type[pl.LazyFrame],
|
|
89
|
+
) -> None:
|
|
90
|
+
first = df_type({"a": [3, 4, 5]}) # NOTE: first two rows are violations
|
|
91
|
+
second = df_type({"a": ["1", "2", "3"]})
|
|
92
|
+
|
|
93
|
+
_, failure_info = Collection.filter(
|
|
94
|
+
{"first": first, "second": second}, # type: ignore
|
|
95
|
+
cast=True,
|
|
96
|
+
eager=False,
|
|
97
|
+
)
|
|
98
|
+
assert failure_info["first"].counts() == {"a|min": 2}
|
|
99
|
+
assert failure_info["second"].counts() == {}
|
|
100
|
+
|
|
101
|
+
_, failure_info = Collection.filter(
|
|
102
|
+
{"first": first, "second": second}, # type: ignore
|
|
103
|
+
cast=True,
|
|
104
|
+
skip_member_validation=True,
|
|
105
|
+
eager=False,
|
|
106
|
+
)
|
|
107
|
+
assert failure_info["first"].counts() == {}
|
|
108
|
+
assert failure_info["second"].counts() == {}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dataframely-2.12.0 → dataframely-2.13.0}/tests/collection/test_collection_future_annotations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|