From 6643fe32ed5db0098d8365580c9887dbcbbd708d Mon Sep 17 00:00:00 2001 From: Oliver Borchert Date: Sat, 25 Oct 2025 03:17:03 +0200 Subject: [PATCH 1/5] docs: Revamp documentation with pydata theme --- .gitignore | 1 + .pre-commit-config.yaml | 1 + dataframely/columns/_base.py | 2 +- dataframely/columns/any.py | 2 +- dataframely/columns/array.py | 2 +- dataframely/columns/categorical.py | 2 +- dataframely/columns/datetime.py | 8 +- dataframely/columns/decimal.py | 2 +- dataframely/columns/enum.py | 2 +- dataframely/columns/float.py | 2 +- dataframely/columns/integer.py | 2 +- dataframely/columns/list.py | 2 +- dataframely/columns/object.py | 2 +- dataframely/columns/string.py | 2 +- dataframely/columns/struct.py | 2 +- dataframely/exc.py | 2 +- dataframely/filter_result.py | 6 +- dataframely/schema.py | 16 +- docs/_api/dataframely.collection.rst | 26 - docs/_api/dataframely.columns.any.rst | 7 - docs/_api/dataframely.columns.bool.rst | 7 - docs/_api/dataframely.columns.datetime.rst | 7 - docs/_api/dataframely.columns.decimal.rst | 7 - docs/_api/dataframely.columns.enum.rst | 7 - docs/_api/dataframely.columns.float.rst | 7 - docs/_api/dataframely.columns.integer.rst | 7 - docs/_api/dataframely.columns.list.rst | 7 - docs/_api/dataframely.columns.rst | 122 ---- docs/_api/dataframely.columns.string.rst | 7 - docs/_api/dataframely.columns.struct.rst | 7 - docs/_api/dataframely.config.rst | 7 - docs/_api/dataframely.exc.rst | 7 - docs/_api/dataframely.failure.rst | 7 - docs/_api/dataframely.functional.rst | 7 - docs/_api/dataframely.mypy.rst | 7 - docs/_api/dataframely.random.rst | 7 - docs/_api/dataframely.rst | 76 --- docs/_api/dataframely.schema.rst | 7 - docs/_api/dataframely.testing.const.rst | 7 - docs/_api/dataframely.testing.factory.rst | 7 - docs/_api/dataframely.testing.mask.rst | 7 - docs/_api/dataframely.testing.rst | 50 -- docs/_api/dataframely.testing.rules.rst | 7 - docs/_api/dataframely.testing.typing.rst | 7 - docs/_api/modules.rst | 7 - docs/_templates/autosummary/class.rst | 12 + docs/_templates/autosummary/method.rst | 9 + docs/_templates/classes/column.rst | 13 + docs/_templates/classes/filter_result.rst | 14 + docs/api/collection/filters.rst | 10 + docs/api/collection/generation.rst | 10 + docs/api/collection/index.rst | 21 + docs/api/collection/io.rst | 37 ++ docs/api/collection/metadata.rst | 17 + docs/api/collection/operations.rst | 11 + docs/api/collection/validation.rst | 12 + docs/api/columns/index.rst | 36 ++ docs/api/filter_result/failure_info.rst | 37 ++ docs/api/filter_result/index.rst | 19 + docs/api/index.rst | 40 ++ docs/api/misc/index.rst | 13 + docs/api/schema/conversion.rst | 11 + docs/api/schema/generation.rst | 11 + docs/api/schema/index.rst | 20 + docs/api/schema/io.rst | 37 ++ docs/api/schema/metadata.rst | 12 + docs/api/schema/validation.rst | 12 + docs/conf.py | 118 ++-- docs/css/custom.css | 4 + docs/{sites => guides}/development.md | 0 docs/guides/examples/index.md | 8 + .../examples/real-world.ipynb | 40 +- docs/{sites => guides}/faq.md | 0 .../features/column-metadata.md | 0 .../features/data-generation.md | 0 docs/{sites => guides}/features/index.md | 2 + .../features/primary-keys.md | 0 .../features/serialization.md | 0 .../features/sql-generation.md | 0 .../installation.md => guides/index.md} | 16 +- docs/{sites => guides}/quickstart.md | 0 docs/{sites => guides}/versioning.md | 0 docs/index.md | 28 +- pixi.lock | 565 ++++++++++++++++-- pixi.toml | 10 +- 85 files changed, 1094 insertions(+), 604 deletions(-) delete mode 100644 docs/_api/dataframely.collection.rst delete mode 100644 docs/_api/dataframely.columns.any.rst delete mode 100644 docs/_api/dataframely.columns.bool.rst delete mode 100644 docs/_api/dataframely.columns.datetime.rst delete mode 100644 docs/_api/dataframely.columns.decimal.rst delete mode 100644 docs/_api/dataframely.columns.enum.rst delete mode 100644 docs/_api/dataframely.columns.float.rst delete mode 100644 docs/_api/dataframely.columns.integer.rst delete mode 100644 docs/_api/dataframely.columns.list.rst delete mode 100644 docs/_api/dataframely.columns.rst delete mode 100644 docs/_api/dataframely.columns.string.rst delete mode 100644 docs/_api/dataframely.columns.struct.rst delete mode 100644 docs/_api/dataframely.config.rst delete mode 100644 docs/_api/dataframely.exc.rst delete mode 100644 docs/_api/dataframely.failure.rst delete mode 100644 docs/_api/dataframely.functional.rst delete mode 100644 docs/_api/dataframely.mypy.rst delete mode 100644 docs/_api/dataframely.random.rst delete mode 100644 docs/_api/dataframely.rst delete mode 100644 docs/_api/dataframely.schema.rst delete mode 100644 docs/_api/dataframely.testing.const.rst delete mode 100644 docs/_api/dataframely.testing.factory.rst delete mode 100644 docs/_api/dataframely.testing.mask.rst delete mode 100644 docs/_api/dataframely.testing.rst delete mode 100644 docs/_api/dataframely.testing.rules.rst delete mode 100644 docs/_api/dataframely.testing.typing.rst delete mode 100644 docs/_api/modules.rst create mode 100644 docs/_templates/autosummary/class.rst create mode 100644 docs/_templates/autosummary/method.rst create mode 100644 docs/_templates/classes/column.rst create mode 100644 docs/_templates/classes/filter_result.rst create mode 100644 docs/api/collection/filters.rst create mode 100644 docs/api/collection/generation.rst create mode 100644 docs/api/collection/index.rst create mode 100644 docs/api/collection/io.rst create mode 100644 docs/api/collection/metadata.rst create mode 100644 docs/api/collection/operations.rst create mode 100644 docs/api/collection/validation.rst create mode 100644 docs/api/columns/index.rst create mode 100644 docs/api/filter_result/failure_info.rst create mode 100644 docs/api/filter_result/index.rst create mode 100644 docs/api/index.rst create mode 100644 docs/api/misc/index.rst create mode 100644 docs/api/schema/conversion.rst create mode 100644 docs/api/schema/generation.rst create mode 100644 docs/api/schema/index.rst create mode 100644 docs/api/schema/io.rst create mode 100644 docs/api/schema/metadata.rst create mode 100644 docs/api/schema/validation.rst create mode 100644 docs/css/custom.css rename docs/{sites => guides}/development.md (100%) create mode 100644 docs/guides/examples/index.md rename docs/{sites => guides}/examples/real-world.ipynb (95%) rename docs/{sites => guides}/faq.md (100%) rename docs/{sites => guides}/features/column-metadata.md (100%) rename docs/{sites => guides}/features/data-generation.md (100%) rename docs/{sites => guides}/features/index.md (88%) rename docs/{sites => guides}/features/primary-keys.md (100%) rename docs/{sites => guides}/features/serialization.md (100%) rename docs/{sites => guides}/features/sql-generation.md (100%) rename docs/{sites/installation.md => guides/index.md} (51%) rename docs/{sites => guides}/quickstart.md (100%) rename docs/{sites => guides}/versioning.md (100%) diff --git a/.gitignore b/.gitignore index c072bb9f..d24d6aac 100644 --- a/.gitignore +++ b/.gitignore @@ -213,6 +213,7 @@ instance/ # Sphinx documentation docs/_build/ +docs/**/_gen/ # PyBuilder .pybuilder/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5fdc98f8..496dc4ef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -93,6 +93,7 @@ repos: entry: pixi run -e lint check-merge-conflict --assume-in-merge language: system types: [text] + exclude: \.rst$ # typos - id: typos name: typos diff --git a/dataframely/columns/_base.py b/dataframely/columns/_base.py index 8237d6d4..f2c863e8 100644 --- a/dataframely/columns/_base.py +++ b/dataframely/columns/_base.py @@ -64,7 +64,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/any.py b/dataframely/columns/any.py index bb270db6..8c5de3d5 100644 --- a/dataframely/columns/any.py +++ b/dataframely/columns/any.py @@ -41,7 +41,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/array.py b/dataframely/columns/array.py index 0460b85b..2ff1b067 100644 --- a/dataframely/columns/array.py +++ b/dataframely/columns/array.py @@ -57,7 +57,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/categorical.py b/dataframely/columns/categorical.py index f5687364..c1cbddeb 100644 --- a/dataframely/columns/categorical.py +++ b/dataframely/columns/categorical.py @@ -45,7 +45,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/datetime.py b/dataframely/columns/datetime.py index ca11b389..a7069cbb 100644 --- a/dataframely/columns/datetime.py +++ b/dataframely/columns/datetime.py @@ -73,7 +73,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different @@ -196,7 +196,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different @@ -331,7 +331,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different @@ -472,7 +472,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/decimal.py b/dataframely/columns/decimal.py index 342f6a3b..9a072ea7 100644 --- a/dataframely/columns/decimal.py +++ b/dataframely/columns/decimal.py @@ -63,7 +63,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/enum.py b/dataframely/columns/enum.py index 38b51bec..00d1dd92 100644 --- a/dataframely/columns/enum.py +++ b/dataframely/columns/enum.py @@ -52,7 +52,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/float.py b/dataframely/columns/float.py index 383575da..1c2ba7d1 100644 --- a/dataframely/columns/float.py +++ b/dataframely/columns/float.py @@ -64,7 +64,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/integer.py b/dataframely/columns/integer.py index cfa7348a..e3049bff 100644 --- a/dataframely/columns/integer.py +++ b/dataframely/columns/integer.py @@ -61,7 +61,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/list.py b/dataframely/columns/list.py index 37898665..0804cf10 100644 --- a/dataframely/columns/list.py +++ b/dataframely/columns/list.py @@ -61,7 +61,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/object.py b/dataframely/columns/object.py index 2da8106c..62b74380 100644 --- a/dataframely/columns/object.py +++ b/dataframely/columns/object.py @@ -41,7 +41,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/string.py b/dataframely/columns/string.py index 90a4e0fd..fadb4f25 100644 --- a/dataframely/columns/string.py +++ b/dataframely/columns/string.py @@ -53,7 +53,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/columns/struct.py b/dataframely/columns/struct.py index 8284720f..ea6a687c 100644 --- a/dataframely/columns/struct.py +++ b/dataframely/columns/struct.py @@ -56,7 +56,7 @@ def __init__( in the same name, the suffix __i is appended to the name. - A dictionary mapping rule names to callables, where each callable returns a non-aggregated boolean expression. - All rule names provided here are given the prefix "check_". + All rule names provided here are given the prefix `"check_"`. alias: An overwrite for this column's name which allows for using a column name that is not a valid Python identifier. Especially note that setting this option does _not_ allow to refer to the column with two different diff --git a/dataframely/exc.py b/dataframely/exc.py index 8c24a07b..a87497a7 100644 --- a/dataframely/exc.py +++ b/dataframely/exc.py @@ -40,4 +40,4 @@ def __init__(self, attr: str, kls: type) -> None: class ValidationRequiredError(Exception): - """Error raised when validation is when reading a parquet file.""" + """Error raised when validation is required when reading a parquet file.""" diff --git a/dataframely/filter_result.py b/dataframely/filter_result.py index f5fafc3d..3ca3b5ee 100644 --- a/dataframely/filter_result.py +++ b/dataframely/filter_result.py @@ -89,7 +89,7 @@ class FailureInfo(Generic[S]): #: The subset of the input data frame containing the *invalid* rows along with #: all boolean columns used for validation. Each of these boolean columns describes - #: a single rule where a value of `False``` indicates unsuccessful validation. + #: a single rule where a value of `False` indicates unsuccessful validation. #: Thus, at least one value per row is `False`. _lf: pl.LazyFrame #: The columns in `_lf` which are used for validation. @@ -150,7 +150,7 @@ def write_parquet(self, file: str | Path | IO[bytes], **kwargs: Any) -> None: parquet file. This should be a path to a directory if writing a partitioned dataset. kwargs: Additional keyword arguments passed directly to - :meth:`polars.write_parquet`. `metadata` may only be provided if it + :meth:`polars.write_parquet`. ``metadata`` may only be provided if it is a dictionary. Attention: @@ -169,7 +169,7 @@ def sink_parquet( parquet file. This should be a path to a directory if writing a partitioned dataset. kwargs: Additional keyword arguments passed directly to - :meth:`polars.sink_parquet`. `metadata` may only be provided if it + :meth:`polars.sink_parquet`. ``metadata`` may only be provided if it is a dictionary. Attention: diff --git a/dataframely/schema.py b/dataframely/schema.py index f91b97d4..104ddf26 100644 --- a/dataframely/schema.py +++ b/dataframely/schema.py @@ -893,9 +893,9 @@ def read_parquet( returns if the schema stored in the parquet file's metadata matches this schema. - `"skip"`: The method never runs validation and simply reads the - parquet file, entrusting the user that the schema is valid. _Use this + parquet file, entrusting the user that the schema is valid. *Use this option carefully and consider replacing it with - :meth:`polars.read_parquet` to convey the purpose better_. + :meth:`polars.read_parquet` to convey the purpose better*. kwargs: Additional keyword arguments passed directly to :meth:`polars.read_parquet`. @@ -949,9 +949,9 @@ def scan_parquet( returns if the schema stored in the parquet file's metadata matches this schema. - `"skip"`: The method never runs validation and simply reads the - parquet file, entrusting the user that the schema is valid. _Use this + parquet file, entrusting the user that the schema is valid. *Use this option carefully and consider replacing it with - :meth:`polars.scan_parquet` to convey the purpose better_. + :meth:`polars.scan_parquet` to convey the purpose better*. kwargs: Additional keyword arguments passed directly to :meth:`polars.scan_parquet`. @@ -1076,9 +1076,9 @@ def scan_delta( returns if the schema stored in the parquet file's metadata matches this schema. - `"skip"`: The method never runs validation and simply reads the - parquet file, entrusting the user that the schema is valid. _Use this + parquet file, entrusting the user that the schema is valid. *Use this option carefully and consider replacing it with - :meth:`polars.scan_delta` to convey the purpose better_. + :meth:`polars.scan_delta` to convey the purpose better*. kwargs: Additional keyword arguments passed directly to :meth:`polars.scan_delta`. @@ -1133,9 +1133,9 @@ def read_delta( returns if the schema stored in the parquet file's metadata matches this schema. - `"skip"`: The method never runs validation and simply reads the - parquet file, entrusting the user that the schema is valid. _Use this + parquet file, entrusting the user that the schema is valid. *Use this option carefully and consider replacing it with - :meth:`polars.read_delta` to convey the purpose better_. + :meth:`polars.read_delta` to convey the purpose better*. kwargs: Additional keyword arguments passed directly to :meth:`polars.read_delta`. diff --git a/docs/_api/dataframely.collection.rst b/docs/_api/dataframely.collection.rst deleted file mode 100644 index ea9b799b..00000000 --- a/docs/_api/dataframely.collection.rst +++ /dev/null @@ -1,26 +0,0 @@ -dataframely.collection package -============================== - -.. automodule:: dataframely.collection - :members: - :show-inheritance: - :undoc-members: - -Submodules ----------- - -dataframely.collection.collection module ----------------------------------------- - -.. automodule:: dataframely.collection.collection - :members: - :show-inheritance: - :undoc-members: - -dataframely.collection.filter\_result module --------------------------------------------- - -.. automodule:: dataframely.collection.filter_result - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.any.rst b/docs/_api/dataframely.columns.any.rst deleted file mode 100644 index a4aae64d..00000000 --- a/docs/_api/dataframely.columns.any.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.any module -============================== - -.. automodule:: dataframely.columns.any - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.bool.rst b/docs/_api/dataframely.columns.bool.rst deleted file mode 100644 index 8b815979..00000000 --- a/docs/_api/dataframely.columns.bool.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.bool module -=============================== - -.. automodule:: dataframely.columns.bool - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.datetime.rst b/docs/_api/dataframely.columns.datetime.rst deleted file mode 100644 index 114ea6b9..00000000 --- a/docs/_api/dataframely.columns.datetime.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.datetime module -=================================== - -.. automodule:: dataframely.columns.datetime - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.decimal.rst b/docs/_api/dataframely.columns.decimal.rst deleted file mode 100644 index f11550e1..00000000 --- a/docs/_api/dataframely.columns.decimal.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.decimal module -================================== - -.. automodule:: dataframely.columns.decimal - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.enum.rst b/docs/_api/dataframely.columns.enum.rst deleted file mode 100644 index fd0b9967..00000000 --- a/docs/_api/dataframely.columns.enum.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.enum module -=============================== - -.. automodule:: dataframely.columns.enum - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.float.rst b/docs/_api/dataframely.columns.float.rst deleted file mode 100644 index 30f01ca3..00000000 --- a/docs/_api/dataframely.columns.float.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.float module -================================ - -.. automodule:: dataframely.columns.float - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.integer.rst b/docs/_api/dataframely.columns.integer.rst deleted file mode 100644 index 44269e98..00000000 --- a/docs/_api/dataframely.columns.integer.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.integer module -================================== - -.. automodule:: dataframely.columns.integer - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.list.rst b/docs/_api/dataframely.columns.list.rst deleted file mode 100644 index 6a9e2610..00000000 --- a/docs/_api/dataframely.columns.list.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.list module -=============================== - -.. automodule:: dataframely.columns.list - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.rst b/docs/_api/dataframely.columns.rst deleted file mode 100644 index 01f07526..00000000 --- a/docs/_api/dataframely.columns.rst +++ /dev/null @@ -1,122 +0,0 @@ -dataframely.columns package -=========================== - -.. automodule:: dataframely.columns - :members: - :show-inheritance: - :undoc-members: - -Submodules ----------- - -dataframely.columns.any module ------------------------------- - -.. automodule:: dataframely.columns.any - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.array module --------------------------------- - -.. automodule:: dataframely.columns.array - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.binary module ---------------------------------- - -.. automodule:: dataframely.columns.binary - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.bool module -------------------------------- - -.. automodule:: dataframely.columns.bool - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.categorical module --------------------------------------- - -.. automodule:: dataframely.columns.categorical - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.datetime module ------------------------------------ - -.. automodule:: dataframely.columns.datetime - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.decimal module ----------------------------------- - -.. automodule:: dataframely.columns.decimal - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.enum module -------------------------------- - -.. automodule:: dataframely.columns.enum - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.float module --------------------------------- - -.. automodule:: dataframely.columns.float - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.integer module ----------------------------------- - -.. automodule:: dataframely.columns.integer - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.list module -------------------------------- - -.. automodule:: dataframely.columns.list - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.object module ---------------------------------- - -.. automodule:: dataframely.columns.object - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.string module ---------------------------------- - -.. automodule:: dataframely.columns.string - :members: - :show-inheritance: - :undoc-members: - -dataframely.columns.struct module ---------------------------------- - -.. automodule:: dataframely.columns.struct - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.string.rst b/docs/_api/dataframely.columns.string.rst deleted file mode 100644 index 3a702e1a..00000000 --- a/docs/_api/dataframely.columns.string.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.string module -================================= - -.. automodule:: dataframely.columns.string - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.columns.struct.rst b/docs/_api/dataframely.columns.struct.rst deleted file mode 100644 index 8b4653c4..00000000 --- a/docs/_api/dataframely.columns.struct.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.columns.struct module -================================= - -.. automodule:: dataframely.columns.struct - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.config.rst b/docs/_api/dataframely.config.rst deleted file mode 100644 index ef6d04f4..00000000 --- a/docs/_api/dataframely.config.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.config module -========================= - -.. automodule:: dataframely.config - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.exc.rst b/docs/_api/dataframely.exc.rst deleted file mode 100644 index 86fd11bb..00000000 --- a/docs/_api/dataframely.exc.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.exc module -====================== - -.. automodule:: dataframely.exc - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.failure.rst b/docs/_api/dataframely.failure.rst deleted file mode 100644 index fcb28419..00000000 --- a/docs/_api/dataframely.failure.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.failure module -========================== - -.. automodule:: dataframely.failure - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.functional.rst b/docs/_api/dataframely.functional.rst deleted file mode 100644 index 154d7b3f..00000000 --- a/docs/_api/dataframely.functional.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.functional module -============================= - -.. automodule:: dataframely.functional - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.mypy.rst b/docs/_api/dataframely.mypy.rst deleted file mode 100644 index 2f6b4fbb..00000000 --- a/docs/_api/dataframely.mypy.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.mypy module -======================= - -.. automodule:: dataframely.mypy - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.random.rst b/docs/_api/dataframely.random.rst deleted file mode 100644 index 9226a9af..00000000 --- a/docs/_api/dataframely.random.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.random module -========================= - -.. automodule:: dataframely.random - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.rst b/docs/_api/dataframely.rst deleted file mode 100644 index 89b01d90..00000000 --- a/docs/_api/dataframely.rst +++ /dev/null @@ -1,76 +0,0 @@ -dataframely package -=================== - -.. automodule:: dataframely - :members: - :show-inheritance: - :undoc-members: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - dataframely.collection - dataframely.columns - dataframely.testing - -Submodules ----------- - -dataframely.config module -------------------------- - -.. automodule:: dataframely.config - :members: - :show-inheritance: - :undoc-members: - -dataframely.exc module ----------------------- - -.. automodule:: dataframely.exc - :members: - :show-inheritance: - :undoc-members: - -dataframely.filter\_result module ---------------------------------- - -.. automodule:: dataframely.filter_result - :members: - :show-inheritance: - :undoc-members: - -dataframely.functional module ------------------------------ - -.. automodule:: dataframely.functional - :members: - :show-inheritance: - :undoc-members: - -dataframely.mypy module ------------------------ - -.. automodule:: dataframely.mypy - :members: - :show-inheritance: - :undoc-members: - -dataframely.random module -------------------------- - -.. automodule:: dataframely.random - :members: - :show-inheritance: - :undoc-members: - -dataframely.schema module -------------------------- - -.. automodule:: dataframely.schema - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.schema.rst b/docs/_api/dataframely.schema.rst deleted file mode 100644 index 1c292a40..00000000 --- a/docs/_api/dataframely.schema.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.schema module -========================= - -.. automodule:: dataframely.schema - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.testing.const.rst b/docs/_api/dataframely.testing.const.rst deleted file mode 100644 index 418df868..00000000 --- a/docs/_api/dataframely.testing.const.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.testing.const module -================================ - -.. automodule:: dataframely.testing.const - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.testing.factory.rst b/docs/_api/dataframely.testing.factory.rst deleted file mode 100644 index 355e4470..00000000 --- a/docs/_api/dataframely.testing.factory.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.testing.factory module -================================== - -.. automodule:: dataframely.testing.factory - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.testing.mask.rst b/docs/_api/dataframely.testing.mask.rst deleted file mode 100644 index ce389845..00000000 --- a/docs/_api/dataframely.testing.mask.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.testing.mask module -=============================== - -.. automodule:: dataframely.testing.mask - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.testing.rst b/docs/_api/dataframely.testing.rst deleted file mode 100644 index fda003a4..00000000 --- a/docs/_api/dataframely.testing.rst +++ /dev/null @@ -1,50 +0,0 @@ -dataframely.testing package -=========================== - -.. automodule:: dataframely.testing - :members: - :show-inheritance: - :undoc-members: - -Submodules ----------- - -dataframely.testing.const module --------------------------------- - -.. automodule:: dataframely.testing.const - :members: - :show-inheritance: - :undoc-members: - -dataframely.testing.factory module ----------------------------------- - -.. automodule:: dataframely.testing.factory - :members: - :show-inheritance: - :undoc-members: - -dataframely.testing.mask module -------------------------------- - -.. automodule:: dataframely.testing.mask - :members: - :show-inheritance: - :undoc-members: - -dataframely.testing.rules module --------------------------------- - -.. automodule:: dataframely.testing.rules - :members: - :show-inheritance: - :undoc-members: - -dataframely.testing.storage module ----------------------------------- - -.. automodule:: dataframely.testing.storage - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.testing.rules.rst b/docs/_api/dataframely.testing.rules.rst deleted file mode 100644 index 7abf839a..00000000 --- a/docs/_api/dataframely.testing.rules.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.testing.rules module -================================ - -.. automodule:: dataframely.testing.rules - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/dataframely.testing.typing.rst b/docs/_api/dataframely.testing.typing.rst deleted file mode 100644 index 26ede4c8..00000000 --- a/docs/_api/dataframely.testing.typing.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely.testing.typing module -================================= - -.. automodule:: dataframely.testing.typing - :members: - :show-inheritance: - :undoc-members: diff --git a/docs/_api/modules.rst b/docs/_api/modules.rst deleted file mode 100644 index 84e9d107..00000000 --- a/docs/_api/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -dataframely -=========== - -.. toctree:: - :maxdepth: 4 - - dataframely diff --git a/docs/_templates/autosummary/class.rst b/docs/_templates/autosummary/class.rst new file mode 100644 index 00000000..8385e2a1 --- /dev/null +++ b/docs/_templates/autosummary/class.rst @@ -0,0 +1,12 @@ +:html_theme.sidebar_secondary.remove: true + +.. role:: hidden + +{{ name | underline }} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ name }} + :members: + :autosummary: + :autosummary-nosignatures: diff --git a/docs/_templates/autosummary/method.rst b/docs/_templates/autosummary/method.rst new file mode 100644 index 00000000..40d834ba --- /dev/null +++ b/docs/_templates/autosummary/method.rst @@ -0,0 +1,9 @@ +:html_theme.sidebar_secondary.remove: true + +.. role:: hidden + +{{ (class + "." + name) | underline }} + +.. currentmodule:: {{ module }} + +.. automethod:: {{ class }}.{{ name }} diff --git a/docs/_templates/classes/column.rst b/docs/_templates/classes/column.rst new file mode 100644 index 00000000..032988b5 --- /dev/null +++ b/docs/_templates/classes/column.rst @@ -0,0 +1,13 @@ +:html_theme.sidebar_secondary.remove: true + +.. role:: hidden + +{{ name | underline }} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ name }} + :members: + :exclude-members: as_dict, from_dict, matches, pyarrow_field, pyarrow_dtype, sqlalchemy_dtype, sqlalchemy_column, validate_dtype, validation_rules + :autosummary: + :autosummary-nosignatures: diff --git a/docs/_templates/classes/filter_result.rst b/docs/_templates/classes/filter_result.rst new file mode 100644 index 00000000..d35fe636 --- /dev/null +++ b/docs/_templates/classes/filter_result.rst @@ -0,0 +1,14 @@ +:html_theme.sidebar_secondary.remove: true + +.. role:: hidden + +{{ name | underline }} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ name }} + :members: + :class-doc-from: class + :exclude-members: count, index + :autosummary: + :autosummary-nosignatures: diff --git a/docs/api/collection/filters.rst b/docs/api/collection/filters.rst new file mode 100644 index 00000000..7bca0fba --- /dev/null +++ b/docs/api/collection/filters.rst @@ -0,0 +1,10 @@ +======= +Filters +======= + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + require_relationship_one_to_one + require_relationship_one_to_at_least_one diff --git a/docs/api/collection/generation.rst b/docs/api/collection/generation.rst new file mode 100644 index 00000000..07acab40 --- /dev/null +++ b/docs/api/collection/generation.rst @@ -0,0 +1,10 @@ +=============== +Data Generation +=============== + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Collection.create_empty + Collection.sample diff --git a/docs/api/collection/index.rst b/docs/api/collection/index.rst new file mode 100644 index 00000000..5356a85a --- /dev/null +++ b/docs/api/collection/index.rst @@ -0,0 +1,21 @@ +========== +Collection +========== + +.. toctree:: + :maxdepth: 2 + :hidden: + + validation + io + generation + operations + metadata + filters + +.. currentmodule:: dataframely +.. autoclass:: Collection + :members: + :noindex: + :autosummary: + :autosummary-nosignatures: diff --git a/docs/api/collection/io.rst b/docs/api/collection/io.rst new file mode 100644 index 00000000..a90ff54d --- /dev/null +++ b/docs/api/collection/io.rst @@ -0,0 +1,37 @@ +=== +I/O +=== + +Writing Data +------------ + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Collection.write_parquet + Collection.sink_parquet + Collection.write_delta + +Reading Data +------------ + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Collection.read_parquet + Collection.scan_parquet + Collection.read_delta + Collection.scan_delta + +Collection Serialization +------------------------ + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Collection.serialize + deserialize_collection + read_parquet_metadata_collection diff --git a/docs/api/collection/metadata.rst b/docs/api/collection/metadata.rst new file mode 100644 index 00000000..907ff2c2 --- /dev/null +++ b/docs/api/collection/metadata.rst @@ -0,0 +1,17 @@ +======== +Metadata +======== + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Collection.members + Collection.member_schemas + Collection.required_members + Collection.optional_members + Collection.non_ignored_members + Collection.ignored_members + Collection.common_primary_key + Collection.matches + Collection.to_dict diff --git a/docs/api/collection/operations.rst b/docs/api/collection/operations.rst new file mode 100644 index 00000000..46b1000b --- /dev/null +++ b/docs/api/collection/operations.rst @@ -0,0 +1,11 @@ +========== +Operations +========== + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Collection.collect_all + Collection.join + concat_collection_members diff --git a/docs/api/collection/validation.rst b/docs/api/collection/validation.rst new file mode 100644 index 00000000..132eec19 --- /dev/null +++ b/docs/api/collection/validation.rst @@ -0,0 +1,12 @@ +========== +Validation +========== + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Collection.validate + Collection.filter + Collection.is_valid + Collection.cast diff --git a/docs/api/columns/index.rst b/docs/api/columns/index.rst new file mode 100644 index 00000000..634cef7c --- /dev/null +++ b/docs/api/columns/index.rst @@ -0,0 +1,36 @@ +======= +Columns +======= + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + :template: classes/column.rst + + Any + Array + Binary + Bool + Categorical + Date + Datetime + Decimal + Duration + Enum + Float + Float32 + Float64 + Int8 + Int16 + Int32 + Int64 + Integer + List + Object + String + Struct + Time + UInt8 + UInt16 + UInt32 + UInt64 diff --git a/docs/api/filter_result/failure_info.rst b/docs/api/filter_result/failure_info.rst new file mode 100644 index 00000000..f471895a --- /dev/null +++ b/docs/api/filter_result/failure_info.rst @@ -0,0 +1,37 @@ +=========== +FailureInfo +=========== + +.. currentmodule:: dataframely +.. autoclass:: FailureInfo + :noindex: + :no-members: + :no-undoc-members: + :no-private-members: + :no-special-members: + :no-inherited-members: + +Inspection +---------- + +.. autosummary:: + :toctree: _gen/ + + FailureInfo.invalid + FailureInfo.counts + FailureInfo.cooccurrence_counts + FailureInfo.__len__ + +I/O +--- + +.. autosummary:: + :toctree: _gen/ + + FailureInfo.write_parquet + FailureInfo.sink_parquet + FailureInfo.read_parquet + FailureInfo.scan_parquet + FailureInfo.write_delta + FailureInfo.read_delta + FailureInfo.scan_delta diff --git a/docs/api/filter_result/index.rst b/docs/api/filter_result/index.rst new file mode 100644 index 00000000..4d4a3a89 --- /dev/null +++ b/docs/api/filter_result/index.rst @@ -0,0 +1,19 @@ +============= +Filter Result +============= + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + :template: classes/filter_result.rst + :nosignatures: + + ~filter_result.FilterResult + ~filter_result.LazyFilterResult + ~collection.CollectionFilterResult + +.. toctree:: + :hidden: + :maxdepth: 2 + + failure_info diff --git a/docs/api/index.rst b/docs/api/index.rst new file mode 100644 index 00000000..e0d5ba36 --- /dev/null +++ b/docs/api/index.rst @@ -0,0 +1,40 @@ +============= +API Reference +============= + +.. grid:: + + .. grid-item-card:: + + .. toctree:: + :maxdepth: 1 + + schema/index + + .. grid-item-card:: + + .. toctree:: + :maxdepth: 1 + + collection/index + + .. grid-item-card:: + + .. toctree:: + :maxdepth: 1 + + columns/index + + .. grid-item-card:: + + .. toctree:: + :maxdepth: 1 + + filter_result/index + + .. grid-item-card:: + + .. toctree:: + :maxdepth: 1 + + misc/index diff --git a/docs/api/misc/index.rst b/docs/api/misc/index.rst new file mode 100644 index 00000000..a6a027df --- /dev/null +++ b/docs/api/misc/index.rst @@ -0,0 +1,13 @@ +============= +Miscellaneous +============= + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + :nosignatures: + + Config + random.Generator + testing.create_schema + testing.create_collection diff --git a/docs/api/schema/conversion.rst b/docs/api/schema/conversion.rst new file mode 100644 index 00000000..70906514 --- /dev/null +++ b/docs/api/schema/conversion.rst @@ -0,0 +1,11 @@ +========== +Conversion +========== + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Schema.to_sqlalchemy_columns + Schema.to_pyarrow_schema + Schema.to_polars_schema diff --git a/docs/api/schema/generation.rst b/docs/api/schema/generation.rst new file mode 100644 index 00000000..997dfd70 --- /dev/null +++ b/docs/api/schema/generation.rst @@ -0,0 +1,11 @@ +=============== +Data Generation +=============== + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Schema.create_empty + Schema.create_empty_if_none + Schema.sample diff --git a/docs/api/schema/index.rst b/docs/api/schema/index.rst new file mode 100644 index 00000000..77e03239 --- /dev/null +++ b/docs/api/schema/index.rst @@ -0,0 +1,20 @@ +====== +Schema +====== + +.. toctree:: + :maxdepth: 2 + :hidden: + + validation + io + generation + conversion + metadata + +.. currentmodule:: dataframely +.. autoclass:: Schema + :members: + :noindex: + :autosummary: + :autosummary-nosignatures: diff --git a/docs/api/schema/io.rst b/docs/api/schema/io.rst new file mode 100644 index 00000000..a0c31b3a --- /dev/null +++ b/docs/api/schema/io.rst @@ -0,0 +1,37 @@ +=== +I/O +=== + +Writing Data +------------ + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Schema.write_parquet + Schema.sink_parquet + Schema.write_delta + +Reading Data +------------ + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Schema.read_parquet + Schema.scan_parquet + Schema.read_delta + Schema.scan_delta + +Schema Serialization +-------------------- + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Schema.serialize + deserialize_schema + read_parquet_metadata_schema diff --git a/docs/api/schema/metadata.rst b/docs/api/schema/metadata.rst new file mode 100644 index 00000000..3122bc82 --- /dev/null +++ b/docs/api/schema/metadata.rst @@ -0,0 +1,12 @@ +======== +Metadata +======== + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Schema.column_names + Schema.columns + Schema.primary_key + Schema.matches diff --git a/docs/api/schema/validation.rst b/docs/api/schema/validation.rst new file mode 100644 index 00000000..b8d72a6a --- /dev/null +++ b/docs/api/schema/validation.rst @@ -0,0 +1,12 @@ +========== +Validation +========== + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + + Schema.validate + Schema.filter + Schema.is_valid + Schema.cast diff --git a/docs/conf.py b/docs/conf.py index 1b5c4742..56f37bed 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,17 +9,6 @@ # -- Path setup -------------------------------------------------------------- -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - import datetime import importlib import inspect @@ -27,7 +16,9 @@ import subprocess import sys from subprocess import CalledProcessError -from typing import cast +from typing import Any, cast + +# -- Project information ----------------------------------------------------- _mod = importlib.import_module("dataframely") @@ -37,49 +28,81 @@ author = "QuantCo, Inc." extensions = [ - "nbsphinx", - "numpydoc", - "sphinx_copybutton", + # builtin sphinx + "sphinx.ext.autosummary", "sphinx.ext.autodoc", "sphinx.ext.intersphinx", "sphinx.ext.linkcode", - "sphinxcontrib.apidoc", - "myst_parser", "sphinx.ext.napoleon", + # external + "autodocsumm", + "myst_parser", + "nbsphinx", + "numpydoc", + "sphinx_copybutton", + "sphinx_design", + "sphinx_toolbox.more_autodoc.overloads", ] -myst_parser_config = {"myst_enable_extensions": ["rst_eval_roles"]} -intersphinx_mapping = { - "python": ("https://docs.python.org/3", None), - "polars": ("https://docs.pola.rs/py-polars/html/", None), - "sqlalchemy": ("https://docs.sqlalchemy.org/en/20/", None), + +## sphinx +# html output +html_theme = "pydata_sphinx_theme" +pygments_style = "lovelace" +html_theme_options = { + "external_links": [], + "icon_links": [ + { + "name": "GitHub", + "url": "https://github.com/Quantco/dataframely", + "icon": "fa-brands fa-github", + }, + ], } +html_title = "Dataframely" +html_static_path = ["_static"] +html_css_files = ["css/custom.css"] +html_favicon = "_static/favicon.ico" +html_show_sourcelink = False +# markup +default_role = "code" + +# object signatures +maximum_signature_line_length = 88 + +# source files +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] source_suffix = { ".rst": "restructuredtext", ".txt": "markdown", ".md": "markdown", } -numpydoc_class_members_toctree = False -apidoc_module_dir = "../dataframely" -apidoc_output_dir = "_api" -apidoc_module_first = True -apidoc_extra_args = ["--implicit-namespaces"] +# templating +templates_path = ["_templates"] +## sphinx.ext.autodoc +autoclass_content = "both" autodoc_default_options = { "inherited-members": True, } -templates_path = ["_templates"] -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] -html_theme = "furo" -html_title = "Dataframely" -html_static_path = ["_static"] -html_css_files = ["custom.css"] -html_favicon = "_static/favicon.ico" +## sphinx.ext.intersphinx +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "polars": ("https://docs.pola.rs/py-polars/html/", None), + "sqlalchemy": ("https://docs.sqlalchemy.org/en/20/", None), +} -# Render docstring text in `single backticks` as code. -default_role = "code" +## myst_parser +myst_parser_config = {"myst_enable_extensions": ["rst_eval_roles"]} + +## numpydoc +numpydoc_class_members_toctree = False +numpydoc_show_class_members = False + +## sphinx_toolbox +overloads_location = ["bottom"] # Copied and adapted from @@ -138,3 +161,26 @@ def linkcode_resolve(domain: str, info: dict[str, str]) -> str | None: "https://github.com/quantco/dataframely" f"/blob/{commit}/{_mod.__name__.replace('.', '/')}/{fn}{linespec}" ) + + +## Hide the signature for classes that should not be instantiated by the user +def hide_class_signature( + app: Any, + what: str, + name: str, + obj: Any, + options: Any, + signature: str | None, + return_annotation: str, +) -> tuple[str, str] | None: + if what == "class" and ( + name.endswith("FilterResult") or name.endswith("FailureInfo") + ): + # Return empty signature (no args after the class name) + return "", return_annotation + # Otherwise, keep default behavior + return None + + +def setup(app: Any) -> None: + app.connect("autodoc-process-signature", hide_class_signature) diff --git a/docs/css/custom.css b/docs/css/custom.css new file mode 100644 index 00000000..c7ccd76b --- /dev/null +++ b/docs/css/custom.css @@ -0,0 +1,4 @@ +/* fix visited link colour */ +a:visited { + color: var(--pst-color-link); +} diff --git a/docs/sites/development.md b/docs/guides/development.md similarity index 100% rename from docs/sites/development.md rename to docs/guides/development.md diff --git a/docs/guides/examples/index.md b/docs/guides/examples/index.md new file mode 100644 index 00000000..af285b2c --- /dev/null +++ b/docs/guides/examples/index.md @@ -0,0 +1,8 @@ +# Examples + +```{toctree} +:maxdepth: 1 +:hidden: + +real-world +``` diff --git a/docs/sites/examples/real-world.ipynb b/docs/guides/examples/real-world.ipynb similarity index 95% rename from docs/sites/examples/real-world.ipynb rename to docs/guides/examples/real-world.ipynb index d8f98965..15e39c8b 100644 --- a/docs/sites/examples/real-world.ipynb +++ b/docs/guides/examples/real-world.ipynb @@ -145,13 +145,19 @@ } ], "source": [ - "invoices = pl.DataFrame({\n", - " \"invoice_id\": [\"001\", \"002\", \"003\"],\n", - " \"admission_date\": [date(2025, 1, 1), date(2025, 1, 5), date(2025, 1, 1)],\n", - " \"discharge_date\": [date(2025, 1, 4), date(2025, 1, 7), date(2025, 1, 1)],\n", - " \"received_at\": [datetime(2025, 1, 5), datetime(2025, 1, 8), datetime(2025, 1, 2)],\n", - " \"amount\": [1000.0, 200.0, 400.0]\n", - "})\n", + "invoices = pl.DataFrame(\n", + " {\n", + " \"invoice_id\": [\"001\", \"002\", \"003\"],\n", + " \"admission_date\": [date(2025, 1, 1), date(2025, 1, 5), date(2025, 1, 1)],\n", + " \"discharge_date\": [date(2025, 1, 4), date(2025, 1, 7), date(2025, 1, 1)],\n", + " \"received_at\": [\n", + " datetime(2025, 1, 5),\n", + " datetime(2025, 1, 8),\n", + " datetime(2025, 1, 2),\n", + " ],\n", + " \"amount\": [1000.0, 200.0, 400.0],\n", + " }\n", + ")\n", "\n", "InvoiceSchema.validate(invoices, cast=True)" ] @@ -183,13 +189,19 @@ ], "source": [ "# Raise during validation if there are invalid rows\n", - "invoices = pl.DataFrame({\n", - " \"invoice_id\": [\"001\", \"002\", \"003\"],\n", - " \"admission_date\": [date(2025, 1, 1), date(2025, 1, 5), date(2025, 1, 1)],\n", - " \"discharge_date\": [date(2025, 1, 4), date(2025, 1, 7), date(2025, 1, 1)],\n", - " \"received_at\": [datetime(2025, 1, 5), datetime(2025, 1, 8), datetime(2025, 1, 2)],\n", - " \"amount\": [0.0, 200.0, 400.0], # Invalid amount `0.0` here\n", - "})\n", + "invoices = pl.DataFrame(\n", + " {\n", + " \"invoice_id\": [\"001\", \"002\", \"003\"],\n", + " \"admission_date\": [date(2025, 1, 1), date(2025, 1, 5), date(2025, 1, 1)],\n", + " \"discharge_date\": [date(2025, 1, 4), date(2025, 1, 7), date(2025, 1, 1)],\n", + " \"received_at\": [\n", + " datetime(2025, 1, 5),\n", + " datetime(2025, 1, 8),\n", + " datetime(2025, 1, 2),\n", + " ],\n", + " \"amount\": [0.0, 200.0, 400.0], # Invalid amount `0.0` here\n", + " }\n", + ")\n", "\n", "InvoiceSchema.validate(invoices, cast=True)" ] diff --git a/docs/sites/faq.md b/docs/guides/faq.md similarity index 100% rename from docs/sites/faq.md rename to docs/guides/faq.md diff --git a/docs/sites/features/column-metadata.md b/docs/guides/features/column-metadata.md similarity index 100% rename from docs/sites/features/column-metadata.md rename to docs/guides/features/column-metadata.md diff --git a/docs/sites/features/data-generation.md b/docs/guides/features/data-generation.md similarity index 100% rename from docs/sites/features/data-generation.md rename to docs/guides/features/data-generation.md diff --git a/docs/sites/features/index.md b/docs/guides/features/index.md similarity index 88% rename from docs/sites/features/index.md rename to docs/guides/features/index.md index 32a80551..d45e62c5 100644 --- a/docs/sites/features/index.md +++ b/docs/guides/features/index.md @@ -1,6 +1,8 @@ # Features ```{toctree} +:maxdepth: 1 + column-metadata data-generation primary-keys diff --git a/docs/sites/features/primary-keys.md b/docs/guides/features/primary-keys.md similarity index 100% rename from docs/sites/features/primary-keys.md rename to docs/guides/features/primary-keys.md diff --git a/docs/sites/features/serialization.md b/docs/guides/features/serialization.md similarity index 100% rename from docs/sites/features/serialization.md rename to docs/guides/features/serialization.md diff --git a/docs/sites/features/sql-generation.md b/docs/guides/features/sql-generation.md similarity index 100% rename from docs/sites/features/sql-generation.md rename to docs/guides/features/sql-generation.md diff --git a/docs/sites/installation.md b/docs/guides/index.md similarity index 51% rename from docs/sites/installation.md rename to docs/guides/index.md index c660c7a5..4c25a590 100644 --- a/docs/sites/installation.md +++ b/docs/guides/index.md @@ -1,4 +1,18 @@ -# Installation +# User Guide + +```{toctree} +:maxdepth: 2 +:hidden: + +quickstart +examples/index +features/index +development +versioning +faq +``` + +## Installation To install `dataframely`, use your favorite package manager, e.g., using `pixi` or `pip`: diff --git a/docs/sites/quickstart.md b/docs/guides/quickstart.md similarity index 100% rename from docs/sites/quickstart.md rename to docs/guides/quickstart.md diff --git a/docs/sites/versioning.md b/docs/guides/versioning.md similarity index 100% rename from docs/sites/versioning.md rename to docs/guides/versioning.md diff --git a/docs/index.md b/docs/index.md index a41d7d50..511a4226 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,32 +18,10 @@ schema information to data frame type hints. - Integrate schemas with external tools (e.g., `sqlalchemy` or `pyarrow`) - Generate test data that comply with a schema or collection of schemas and its validation rules -## Contents - ```{toctree} -:caption: Contents :maxdepth: 2 +:hidden: -sites/installation -sites/quickstart -sites/examples/real-world -sites/features/index.md -sites/faq.md -sites/development.md -sites/versioning.md -``` - -## API Documentation - -```{toctree} - :caption: API Documentation - :maxdepth: 1 - - Collection <_api/dataframely.collection> - Column Types <_api/dataframely.columns> - Config <_api/dataframely.config> - Random Data Generation <_api/dataframely.random> - Failure Information <_api/dataframely.failure> - Schema <_api/dataframely.schema> - +guides/index +api/index ``` diff --git a/pixi.lock b/pixi.lock index bd9f84de..cd3cf57f 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1987,9 +1987,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-1.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-core-1.1.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/autodocsumm-0.2.14-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda @@ -1997,24 +2001,32 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py313h7033f15_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cachecontrol-0.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf01b4d8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_100.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cssutils-2.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dict2css-0.3.0.post1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/domdf-python-tools-3.10.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/furo-2024.8.6-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/html5lib-1.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.6.0-pyhfa0c392_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda @@ -2055,9 +2067,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py313h7037e92_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.18.2-py313h07c4f96_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myst-parser-4.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hc388f54_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda @@ -2073,7 +2088,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pbr-7.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.2-pyh145f28c_0.conda @@ -2085,6 +2099,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-h2b335a9_100_cp313.conda @@ -2100,23 +2115,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.27.1-py313h843e2db_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.16-py313h07c4f96_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.14-py313h07c4f96_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-autodoc-typehints-3.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-basic-ng-1.0.0b2-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx_rtd_theme-3.0.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-apidoc-0.3.0-py_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.6.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-jinja2-compat-0.4.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.10.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-tabs-3.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-toolbox-4.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jquery-4.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda @@ -2124,6 +2144,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_inspect-0.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda @@ -2136,9 +2157,13 @@ environments: linux-aarch64: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-1.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-core-1.1.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/autodocsumm-0.2.14-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda @@ -2146,24 +2171,32 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.1.0-py314h02b5315_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_8.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cachecontrol-0.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/cffi-2.0.0-py314h7fea217_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.0-py314hd8ed1ab_101.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cssutils-2.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dict2css-0.3.0.post1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/domdf-python-tools-3.10.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/furo-2024.8.6-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/html5lib-1.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.6.0-pyhfa0c392_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda @@ -2204,9 +2237,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py314hd7d8586_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.18.2-py314h51f160d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myst-parser-4.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hc388f54_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda @@ -2222,7 +2258,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pbr-7.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.2-pyh145f28c_0.conda @@ -2234,6 +2269,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.0-ha9132a3_101_cp314.conda @@ -2249,23 +2285,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rpds-py-0.27.1-py314h7a73458_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.16-py314h51f160d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml.clib-0.2.14-py314h51f160d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-autodoc-typehints-3.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-basic-ng-1.0.0b2-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx_rtd_theme-3.0.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-apidoc-0.3.0-py_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.6.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-jinja2-compat-0.4.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.10.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-tabs-3.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-toolbox-4.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jquery-4.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h5688188_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda @@ -2273,6 +2314,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_inspect-0.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda @@ -2284,9 +2326,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-hbcf94c1_2.conda osx-64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-1.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-core-1.1.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/autodocsumm-0.2.14-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda @@ -2294,24 +2340,32 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/brotli-python-1.1.0-py314hb6723d8_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cachecontrol-0.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-2.0.0-py314h8aa19db_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.0-py314hd8ed1ab_101.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cssutils-2.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dict2css-0.3.0.post1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/domdf-python-tools-3.10.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/furo-2024.8.6-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/html5lib-1.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.6.0-pyhfa0c392_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda @@ -2346,9 +2400,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.2-py314h00ed6fe_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.18.2-py314h6482030_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myst-parser-4.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hc388f54_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda @@ -2364,7 +2421,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pbr-7.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.2-pyh145f28c_0.conda @@ -2376,6 +2432,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.0-h759804c_101_cp314.conda @@ -2391,23 +2448,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.27.1-py314h5e191e8_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.18.16-py314h6482030_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml.clib-0.2.14-py314h6482030_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-autodoc-typehints-3.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-basic-ng-1.0.0b2-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx_rtd_theme-3.0.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-apidoc-0.3.0-py_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.6.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-jinja2-compat-0.4.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.10.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-tabs-3.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-toolbox-4.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jquery-4.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda @@ -2415,6 +2477,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_inspect-0.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda @@ -2426,9 +2489,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h8210216_2.conda osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-1.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-core-1.1.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/autodocsumm-0.2.14-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda @@ -2436,25 +2503,33 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/brotli-python-1.1.0-py314he8615de_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cachecontrol-0.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-2.0.0-py314hb14574c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.0-py314hd8ed1ab_101.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cssutils-2.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dict2css-0.3.0.post1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/domdf-python-tools-3.10.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/furo-2024.8.6-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/html5lib-1.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.6.0-pyhfa0c392_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda @@ -2489,9 +2564,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.1.2-py314h784bc60_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.18.2-py314h0612a62_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myst-parser-4.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hc388f54_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda @@ -2507,7 +2585,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pbr-7.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.2-pyh145f28c_0.conda @@ -2519,6 +2596,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.0-h8929636_101_cp314.conda @@ -2534,23 +2612,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.27.1-py314h65de5f6_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.18.16-py314h0612a62_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.14-py314h0612a62_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-autodoc-typehints-3.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-basic-ng-1.0.0b2-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx_rtd_theme-3.0.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-apidoc-0.3.0-py_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.6.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-jinja2-compat-0.4.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.10.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-tabs-3.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-toolbox-4.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jquery-4.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda @@ -2558,6 +2641,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_inspect-0.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.14-pyhd8ed1ab_0.conda @@ -2570,9 +2654,13 @@ environments: win-64: - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-1.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/apeye-core-1.1.5-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/autodocsumm-0.2.14-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/bleach-6.2.0-pyh29332c3_4.conda @@ -2580,25 +2668,33 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.1.0-py314h13fbf68_4.conda - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.10.5-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cachecontrol-0.14.3-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-2.0.0-py314h5a2d7ad_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.0-py314hd8ed1ab_101.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cssutils-2.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/dict2css-0.3.0.post1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/domdf-python-tools-3.10.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/furo-2024.8.6-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/html5lib-1.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-9.6.0-pyh6be1c34_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython_pygments_lexers-1.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jedi-0.19.2-pyhd8ed1ab_1.conda @@ -2636,9 +2732,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.2.2-h57928b3_16.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.8.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py314h909e829_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.18.2-py314h5a2d7ad_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/myst-parser-4.0.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.6-hc388f54_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda @@ -2653,7 +2752,6 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.5-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pbr-7.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-pyhd8ed1ab_1004.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-25.2-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda @@ -2663,6 +2761,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.1.1-py314h5a2d7ad_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.0-h6fd79ff_101_cp314.conda @@ -2678,23 +2777,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.27.1-py314h49d6ca3_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.16-py314h5a2d7ad_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml.clib-0.2.14-py314h5a2d7ad_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-autodoc-typehints-3.5.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-basic-ng-1.0.0b2-pyhd8ed1ab_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx_rtd_theme-3.0.2-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-apidoc-0.3.0-py_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.6.1-pyhd8ed1ab_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-jinja2-compat-0.4.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.10.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-tabs-3.4.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-toolbox-4.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jquery-4.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-h18a62a1_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda @@ -2703,6 +2807,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_inspect-0.9.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda @@ -8485,6 +8590,16 @@ packages: license_family: MIT size: 8191 timestamp: 1744137672556 +- conda: https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda + sha256: 1307719f0d8ee694fc923579a39c0621c23fdaa14ccdf9278a5aac5665ac58e9 + md5: 74ac5069774cdbc53910ec4d631a3999 + depends: + - pygments + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + size: 1326096 + timestamp: 1734956217254 - conda: https://conda.anaconda.org/conda-forge/noarch/aiobotocore-2.25.0-pyhcf101f3_0.conda sha256: b6ef9f7cc5cd039426b52d082b9ef2847868207200160477e8d668c801f0beab md5: 551693b1068a882aa2143375346b6308 @@ -8972,6 +9087,32 @@ packages: license_family: MIT size: 138159 timestamp: 1758634638734 +- conda: https://conda.anaconda.org/conda-forge/noarch/apeye-1.4.1-pyhd8ed1ab_1.conda + sha256: b554d2d2fc869a5955ebb3e5c8aea5e13ec49363b782b08e1802e29c91beaebf + md5: 0f2a7ba1dfc3b6117cfd864d25fa86ce + depends: + - apeye-core >=1.0.0b2 + - domdf-python-tools >=2.6.0 + - platformdirs >=2.3.0 + - python >=3.9 + - requests >=2.24.0 + constrains: + - cachecontrol >=0.12.6 + license: LGPL-3.0-or-later + license_family: LGPL + size: 95690 + timestamp: 1738250335247 +- conda: https://conda.anaconda.org/conda-forge/noarch/apeye-core-1.1.5-pyhd8ed1ab_1.conda + sha256: 3ee9787c3876c2ffb4b3c77ac73c0b28d67d18a376f4c952643cac95020a2a14 + md5: b60c08c6a0cbb505016075bb9e484e56 + depends: + - domdf-python-tools >=2.6.0 + - idna >=2.5 + - python >=3.9 + license: BSD-3-Clause + license_family: BSD + size: 94258 + timestamp: 1738681346787 - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_1.conda sha256: 8f032b140ea4159806e4969a68b4a3c0a7cab1ad936eb958a2b5ffe5335e19bf md5: 54898d0f524c9dee622d44bbb081a8ab @@ -9206,6 +9347,16 @@ packages: license_family: MIT size: 60101 timestamp: 1759762331492 +- conda: https://conda.anaconda.org/conda-forge/noarch/autodocsumm-0.2.14-pyhd8ed1ab_0.conda + sha256: de413f79691116a0a3eb7a1fb4e6a9dcaab3fce6ab5540fdf5b721525284b504 + md5: 351a11ac1215eb4f6c5b82e30070277a + depends: + - python >=3.7 + - sphinx >=2.2,<9.0 + license: Apache-2.0 + license_family: APACHE + size: 19189 + timestamp: 1729874529249 - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.1-h48c9088_3.conda sha256: e9c3dece30c12dfac995a8386bd2d1225d0b5f14c0753fcf4fef086047f77048 md5: afdbdbe7f786f47a36a51fdc2fe91210 @@ -10931,6 +11082,17 @@ packages: license: ISC size: 155907 timestamp: 1759649036195 +- conda: https://conda.anaconda.org/conda-forge/noarch/cachecontrol-0.14.3-pyha770c72_0.conda + sha256: ec791bb6f1ef504411f87b28946a7ae63ed1f3681cefc462cf1dfdaf0790b6a9 + md5: 241ef6e3db47a143ac34c21bfba510f1 + depends: + - msgpack-python >=0.5.2,<2.0.0 + - python >=3.9 + - requests >=2.16.0 + license: Apache-2.0 + license_family: Apache + size: 23868 + timestamp: 1746103006628 - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 noarch: python sha256: 561e6660f26c35d137ee150187d89767c988413c978e1b712d53f27ddf70ea17 @@ -12186,6 +12348,16 @@ packages: license_family: BSD size: 1491265 timestamp: 1760605228843 +- conda: https://conda.anaconda.org/conda-forge/noarch/cssutils-2.11.1-pyhd8ed1ab_0.conda + sha256: b9006cbd28ed63a6461717cb9234e1d1f39441d9db0493f55ee0ca72f3577833 + md5: 99cf98eea444365238fb6ee8f518ef19 + depends: + - more-itertools + - python >=3.9 + license: LGPL-3.0-only + license_family: LGPL + size: 284664 + timestamp: 1747322864144 - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda sha256: 3b988146a50e165f0fa4e839545c679af88e4782ec284cc7b6d07dd226d6a068 md5: 679616eb5ad4e521c83da4650860aba7 @@ -12401,6 +12573,17 @@ packages: license_family: MIT size: 14382 timestamp: 1737987072859 +- conda: https://conda.anaconda.org/conda-forge/noarch/dict2css-0.3.0.post1-pyhd8ed1ab_1.conda + sha256: 3aa044441dcea3afb935a48a075b59ed14dabb7ee6e019a757ff68d6b13c0a36 + md5: 103dc54172d3083adcda6bf8f1addcf3 + depends: + - cssutils >=2.2.0 + - domdf-python-tools >=2.2.0 + - python >=3.9 + license: MIT + license_family: MIT + size: 13700 + timestamp: 1738250096666 - conda: https://conda.anaconda.org/conda-forge/noarch/distlib-0.4.0-pyhd8ed1ab_0.conda sha256: 6d977f0b2fc24fee21a9554389ab83070db341af6d6f09285360b2e09ef8b26e md5: 003b8ba0a94e2f1e117d0bd46aebc901 @@ -12437,6 +12620,19 @@ packages: license: CC-PDDC AND BSD-3-Clause AND BSD-2-Clause AND ZPL-2.1 size: 437394 timestamp: 1758409808966 +- conda: https://conda.anaconda.org/conda-forge/noarch/domdf-python-tools-3.10.0-pyhff2d567_0.conda + sha256: e7a7121de51caa332e73a0a7345d78fb514a8460311347be5d8eba0738c66c31 + md5: 0254332c3957f0ae09a58670c2d7ea01 + depends: + - importlib-metadata >=3.6.0 + - importlib-resources >=3.0.0 + - natsort >=7.0.1 + - python >=3.9 + - typing-extensions >=3.7.4.1 + license: MIT + license_family: MIT + size: 96253 + timestamp: 1739444562482 - conda: https://conda.anaconda.org/conda-forge/linux-64/editdistance-s-1.0.0-py314h9891dd4_7.conda sha256: 8ec13a26f553445041138bc7d0cfd3909f9059533adcecd3a1f5f29f42f46831 md5: 2111df2165d475f89934dbceeb61110c @@ -13065,6 +13261,17 @@ packages: license_family: MIT size: 30731 timestamp: 1737618390337 +- conda: https://conda.anaconda.org/conda-forge/noarch/html5lib-1.1-pyhd8ed1ab_2.conda + sha256: 8027e436ad59e2a7392f6036392ef9d6c223798d8a1f4f12d5926362def02367 + md5: cf25bfddbd3bc275f3d3f9936cee1dd3 + depends: + - python >=3.9 + - six >=1.9 + - webencodings + license: MIT + license_family: MIT + size: 94853 + timestamp: 1734075276288 - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.9-pyh29332c3_0.conda sha256: 04d49cb3c42714ce533a8553986e1642d0549a05dc5cc48e0d43ff5be6679a5b md5: 4f14640d58e2cc0aa0819d9d8ba125bb @@ -13202,6 +13409,16 @@ packages: license_family: APACHE size: 34641 timestamp: 1747934053147 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda + sha256: a99a3dafdfff2bb648d2b10637c704400295cb2ba6dc929e2d814870cf9f6ae5 + md5: e376ea42e9ae40f3278b0f79c9bf9826 + depends: + - importlib_resources >=6.5.2,<6.5.3.0a0 + - python >=3.9 + license: Apache-2.0 + license_family: APACHE + size: 9724 + timestamp: 1736252443859 - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda sha256: acc1d991837c0afb67c75b77fdc72b4bf022aac71fedd8b9ea45918ac9b08a80 md5: c85c76dc67d75619a92f51dfbce06992 @@ -18004,6 +18221,70 @@ packages: license_family: APACHE size: 4259949 timestamp: 1760741422301 +- conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py313h7037e92_0.conda + sha256: bf8072a1eeb1a5f9c2b215a398762cbd473846e29fbdf81fc4f6c0b75493a734 + md5: 3d35f7d3fd814124efa1a5b5d03144a4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: Apache-2.0 + license_family: Apache + size: 102657 + timestamp: 1759930626652 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/msgpack-python-1.1.2-py314hd7d8586_0.conda + sha256: 51ecd562a674f5c55bfe16e248ba6610d8964e79fafdb7723af25147896474d3 + md5: 94f95ae207adc109d584abf52b9f6a71 + depends: + - libgcc >=14 + - libstdcxx >=14 + - python >=3.14,<3.15.0a0 + - python >=3.14,<3.15.0a0 *_cp314 + - python_abi 3.14.* *_cp314 + license: Apache-2.0 + license_family: Apache + size: 100580 + timestamp: 1759930698962 +- conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.1.2-py314h00ed6fe_0.conda + sha256: 7d44570b39a8146c163636d83b79159f2575f3f987a823eeaefed25c23130d92 + md5: 17023d9e91f032e7afc5e2ebd34dc9cb + depends: + - __osx >=10.13 + - libcxx >=19 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + license: Apache-2.0 + license_family: Apache + size: 92569 + timestamp: 1759930878275 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.1.2-py314h784bc60_0.conda + sha256: 2c850c8c4c545bf4ae2347a85ac1a29ac869a0d57f628e3434964dd7a3d219d8 + md5: 8efef0293783cd291042cc0a7bc446b2 + depends: + - __osx >=11.0 + - libcxx >=19 + - python >=3.14,<3.15.0a0 + - python >=3.14,<3.15.0a0 *_cp314 + - python_abi 3.14.* *_cp314 + license: Apache-2.0 + license_family: Apache + size: 92033 + timestamp: 1759930785729 +- conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.1.2-py314h909e829_0.conda + sha256: 3df55d39858bf7f40d9c9950ef4b48bf4fd257d11c71db57e6556d2e2f768c8e + md5: b591f9ddb678f12b64edd446bf2c6688 + depends: + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + size: 88011 + timestamp: 1759930850633 - conda: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.6.3-py310h89163eb_0.conda sha256: e901bdd27b655ce411b1cda04b5ecabad93d4f4fef929ca46e075678fab5fcf5 md5: 5daf15c40f96f1c2f3721d09e93b66b6 @@ -18690,6 +18971,16 @@ packages: license_family: MIT size: 73074 timestamp: 1739381945342 +- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyh29332c3_1.conda + sha256: 594ae12c32f163f6d312e38de41311a89e476544613df0c1d048f699721621d7 + md5: 0aa03903d33997f3886be58abc890aef + depends: + - python >=3.9 + - python + license: MIT + license_family: MIT + size: 39002 + timestamp: 1733880463101 - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda sha256: a20cff739d66c2f89f413e4ba4c6f6b59c50d5c30b5f0d840c13e8c9c2df9135 md5: 6bb0d77277061742744176ab555b723c @@ -21019,17 +21310,6 @@ packages: license_family: MOZILLA size: 41075 timestamp: 1733233471940 -- conda: https://conda.anaconda.org/conda-forge/noarch/pbr-7.0.1-pyhd8ed1ab_0.conda - sha256: d6678783340fc03410e844652f355422d4f8308fc40b43f87cb36200f6a125a0 - md5: 0d118f1c98cec5ebd0cdfd066e49a446 - depends: - - pip - - python >=3.10 - - setuptools - license: Apache-2.0 - license_family: Apache - size: 79937 - timestamp: 1755795766886 - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda sha256: 5c7380c8fd3ad5fc0f8039069a45586aa452cf165264bc5a437ad80397b32934 md5: 7fa07cb0fb1b625a089ccc01218ee5b1 @@ -22334,6 +22614,22 @@ packages: license_family: MIT size: 1969787 timestamp: 1760442438839 +- conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda + sha256: 073473ba9c0cc3946026dde9112d2edb0ac52f6cc35d2126f4bff8bad1cc74a6 + md5: 837aaf71ddf3b27acae0e7e9015eebc6 + depends: + - accessible-pygments + - babel + - beautifulsoup4 + - docutils !=0.17.0 + - pygments >=2.7 + - python >=3.9 + - sphinx >=6.1 + - typing_extensions + license: BSD-3-Clause + license_family: BSD + size: 1547597 + timestamp: 1734446468767 - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a md5: 6b6ece66ebcae2d5f326c77ef2c5a066 @@ -24641,6 +24937,19 @@ packages: license_family: MIT size: 287401 timestamp: 1756839115184 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml-0.18.16-py313h07c4f96_0.conda + sha256: fa1667f1c61610191960d0f6c33a55f3afacfd9c43ff4c9b1507ba164eb3f28f + md5: 88717b72e54ee6ef081c9ecfafd728c8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ruamel.yaml.clib >=0.1.2 + license: MIT + license_family: MIT + size: 272227 + timestamp: 1761160797563 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.15-py314h51f160d_1.conda sha256: e5c9a36e7e9eed7f529398fd9419d77f7b72247e24202c0e8b67297de81dff84 md5: 98e9fe506db85c2dcfc96d895fba0699 @@ -24654,6 +24963,19 @@ packages: license_family: MIT size: 288811 timestamp: 1756839174443 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ruamel.yaml-0.18.16-py314h51f160d_0.conda + sha256: 4d4b8f2dc37e1fd627a91d72af7691f26348206e2e58bd1e5b7d43f0ea0abde0 + md5: 8b0396e828c1d46552ba4e132943bd30 + depends: + - libgcc >=14 + - python >=3.14,<3.15.0a0 + - python >=3.14,<3.15.0a0 *_cp314 + - python_abi 3.14.* *_cp314 + - ruamel.yaml.clib >=0.1.2 + license: MIT + license_family: MIT + size: 287025 + timestamp: 1761160816065 - conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.18.15-py314h6482030_1.conda sha256: 1b5218e0012f86c854eb9d21eaaf76b0820bdc146a14aecb0145208f3f338840 md5: daf5680baa8386d92c46bc910943efd3 @@ -24666,6 +24988,18 @@ packages: license_family: MIT size: 287938 timestamp: 1756839213185 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ruamel.yaml-0.18.16-py314h6482030_0.conda + sha256: 17d3abfe05839e52090a7d3aa390328f12141ea13b2457eeff1af255db3f0ec3 + md5: 83952d245a9d84bdbfb6ac0a43d5fb29 + depends: + - __osx >=10.13 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + - ruamel.yaml.clib >=0.1.2 + license: MIT + license_family: MIT + size: 288529 + timestamp: 1761160920844 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.18.15-py314h0612a62_1.conda sha256: 5fc0f9fa49904306d770ae769c9ff0bbb885557a37b02541d181a759e76a323e md5: 9c484724f5f1be182b3c89d3dc81519c @@ -24679,6 +25013,19 @@ packages: license_family: MIT size: 287155 timestamp: 1756839251916 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruamel.yaml-0.18.16-py314h0612a62_0.conda + sha256: 6d3d0efb0478386c3d07e3edb043a8818bfa2d3a8bf80428bf3b9dc294ac5d87 + md5: 0bf643e8c39ad9633ce66ab9fcae1042 + depends: + - __osx >=11.0 + - python >=3.14,<3.15.0a0 + - python >=3.14,<3.15.0a0 *_cp314 + - python_abi 3.14.* *_cp314 + - ruamel.yaml.clib >=0.1.2 + license: MIT + license_family: MIT + size: 288328 + timestamp: 1761161205814 - conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.15-py314h5a2d7ad_1.conda sha256: 81c8db96e4e69b7e35b5364bb766a28b4e1051830419c3ecbb8b0b6cfa1eb341 md5: 85eadf42a6403f87f1edfe6cc96bcdfa @@ -24693,6 +25040,32 @@ packages: license_family: MIT size: 288109 timestamp: 1756839148075 +- conda: https://conda.anaconda.org/conda-forge/win-64/ruamel.yaml-0.18.16-py314h5a2d7ad_0.conda + sha256: eafd252c4e2c9942ab9b0c936c2040b3a1525bff73ac70363b5ad0850c582717 + md5: 87d9871a5e6be3c4629f50d147a8d5ca + depends: + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + - ruamel.yaml.clib >=0.1.2 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + size: 287786 + timestamp: 1761160912669 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.14-py313h07c4f96_0.conda + sha256: 1d5607b463001ed480aea45b7f3c1035151c0c44a3bf4f3539a00fe097c5e30a + md5: 3cff82488dd3935fdb3ba37911387fec + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + size: 140261 + timestamp: 1760564339468 - conda: https://conda.anaconda.org/conda-forge/linux-64/ruamel.yaml.clib-0.2.14-py314h5bd0f2a_0.conda sha256: 12a6e9df8cfef6b24776071963b95fa8a6826f5f4879b89b922c661c72284152 md5: 35b2429025596d2835b2f885f3829164 @@ -26084,6 +26457,16 @@ packages: license_family: BSD size: 1424416 timestamp: 1740956642838 +- conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-autodoc-typehints-3.5.2-pyhd8ed1ab_0.conda + sha256: 896309836e7b7682ac7ebf8783d7fde57869d28fa82e0a36413fff41f4049eac + md5: abe9fc17e8bf83725cde006800c926de + depends: + - python >=3.11 + - sphinx >=8.2.3 + license: MIT + license_family: MIT + size: 25344 + timestamp: 1760610604093 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-basic-ng-1.0.0b2-pyhd8ed1ab_3.conda sha256: 90d900d31afe0bd6f42cf1e529e23e6eac4284b48bc64e5e942f19f5bf8ef0f2 md5: a090580065b21d9c56662ebe68f6e7a6 @@ -26104,28 +26487,77 @@ packages: license_family: MIT size: 17893 timestamp: 1734573117732 -- conda: https://conda.anaconda.org/conda-forge/noarch/sphinx_rtd_theme-3.0.2-pyha770c72_0.conda - sha256: c5d1ef5801f56c3bba4088de6c02c10e7f5b195805997fc1af569cf3f33f92e4 - md5: cec0cc87b40171bc323a9d80b619c9c5 +- conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.6.1-pyhd8ed1ab_2.conda + sha256: eb335aef48e49107b55299cedc197f86d05651f1eeff83ed8acf89df7cdc9765 + md5: 3e6c15d914b03f83fc96344f917e0838 depends: - - docutils >0.18,<0.22 - - python >=3.8 + - python >=3.9 - sphinx >=6,<9 - - sphinxcontrib-jquery >=4,<5 license: MIT license_family: MIT - size: 4629955 - timestamp: 1757836585728 -- conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-apidoc-0.3.0-py_1.tar.bz2 - sha256: 6dd136a86576c400b0bdbfffbdba4a35015846a0a7eb1129a1401a17d4f60b19 - md5: 855b087883443abb10f5faf6eef40860 + size: 911336 + timestamp: 1734614675610 +- conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-jinja2-compat-0.4.1-pyhd8ed1ab_0.conda + sha256: 115f4306ace812d90b4ffab5ac27cc01c2fac13df67c5dcc37931130c8ebea13 + md5: 7ecc82915cd2c4654fa26ddc4d3650f7 depends: - - pbr - - python - license: BSD-2-Clause + - jinja2 >=2.10 + - markupsafe >=1 + - python >=3.9 + license: MIT + license_family: MIT + size: 12320 + timestamp: 1754550385132 +- conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.10.1-pyhd8ed1ab_0.conda + sha256: 3d2e0d961b38f66ea3e7decd04917bf69104b6683dae778e4d3ef5291c04b861 + md5: bfc047865de18ef2657bd8a95d7b8b49 + depends: + - pygments + - python >=3.11 + - sphinx + license: BSD-3-Clause license_family: BSD - size: 10555 - timestamp: 1553967001880 + size: 12214 + timestamp: 1758128174284 +- conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-tabs-3.4.1-pyhd8ed1ab_1.conda + sha256: 43c343edc9ea11ffd947d97fa60bf6347a404700e2cde81fb954e60b7e6a42c1 + md5: 8b8362d876396fd967cbb5f404def907 + depends: + - docutils >=0.18.0 + - pygments + - python >=3.6 + - sphinx >=2 + license: MIT + license_family: MIT + size: 15026 + timestamp: 1675342588275 +- conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-toolbox-4.0.0-pyhd8ed1ab_0.conda + sha256: 6244608216a5fff7e96eeaa042d6502e51981f482f451484338566205c5641d1 + md5: 8704cf2160e8059274333aeea143461c + depends: + - apeye >=0.4.0 + - autodocsumm >=0.2.0 + - beautifulsoup4 >=4.9.1 + - cachecontrol >=0.13.0 + - dict2css >=0.2.3 + - docutils >=0.16 + - domdf-python-tools >=2.9.0 + - filelock >=3.8.0 + - html5lib >=1.1 + - python >=3.9 + - ruamel.yaml >=0.16.12 + - sphinx >=3.2.0 + - sphinx-autodoc-typehints >=1.11.1 + - sphinx-jinja2-compat >=0.1.0 + - sphinx-prompt >=1.1.0 + - sphinx-tabs <3.5.0,>=1.2.1 + - tabulate >=0.8.7 + - typing-extensions !=3.10.0.1,>=3.7.4.3 + - typing_inspect >=0.6.0 + license: MIT + license_family: MIT + size: 98309 + timestamp: 1747300447917 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda sha256: d7433a344a9ad32a680b881c81b0034bc61618d12c39dd6e3309abeffa9577ba md5: 16e3f039c0aa6446513e94ab18a8784b @@ -26156,15 +26588,6 @@ packages: license_family: BSD size: 32895 timestamp: 1733754385092 -- conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jquery-4.1-pyhd8ed1ab_1.conda - sha256: 69c08d18663b57ebc8e4187c64c8d29b10996bb465a515cd288d87b6f2f52a5e - md5: 403185829255321ea427333f7773dd1f - depends: - - python >=3.9 - - sphinx >=1.8 - license: 0BSD AND MIT - size: 112964 - timestamp: 1734344603903 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda sha256: 578bef5ec630e5b2b8810d898bbbf79b9ae66d49b7938bcc3efc364e679f2a62 md5: fa839b5ff59e192f411ccc7dae6588bb @@ -26303,6 +26726,15 @@ packages: license_family: MIT size: 26988 timestamp: 1733569565672 +- conda: https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda + sha256: 090023bddd40d83468ef86573976af8c514f64119b2bd814ee63a838a542720a + md5: 959484a66b4b76befcddc4fa97c95567 + depends: + - python >=3.9 + license: MIT + license_family: MIT + size: 37554 + timestamp: 1733589854804 - conda: https://conda.anaconda.org/conda-forge/linux-64/taplo-0.10.0-h2d22210_1.conda sha256: 7d313578d79ece2b328084d906958888b5a474326a24833317d95a71e264b219 md5: a4935b2eea119342f6a9d666e821984d @@ -26640,6 +27072,17 @@ packages: license_family: PSF size: 51692 timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_inspect-0.9.0-pyhd8ed1ab_1.conda + sha256: a3fbdd31b509ff16c7314e8d01c41d9146504df632a360ab30dbc1d3ca79b7c0 + md5: fa31df4d4193aabccaf09ce78a187faf + depends: + - mypy_extensions >=0.3.0 + - python >=3.9 + - typing_extensions >=3.7.4 + license: MIT + license_family: MIT + size: 14919 + timestamp: 1733845966415 - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda sha256: 3088d5d873411a56bf988eee774559335749aed6f6c28e07bf933256afb9eb6c md5: f6d7aa696c67756a650e91e15e88223c diff --git a/pixi.toml b/pixi.toml index f7b86e50..81744cac 100644 --- a/pixi.toml +++ b/pixi.toml @@ -23,20 +23,22 @@ pip = "*" jupyter = "*" [feature.docs.dependencies] +autodocsumm = "*" furo = "*" ipython = "*" make = "*" +pydata-sphinx-theme = "*" # Needed for generating docs for dataframely.mypy mypy = "*" myst-parser = "*" nbsphinx = "*" numpydoc = "*" -sphinx = "*" +sphinx = ">=8.2" sphinx-copybutton = "*" -sphinx_rtd_theme = "*" -sphinxcontrib-apidoc = "*" +sphinx-design = "*" +sphinx-toolbox = "*" [feature.docs.tasks] -docs = { cmd = "sphinx-build -M html . _build", cwd = "docs", depends-on = "postinstall" } +docs = { cmd = "rm -rf _build && find . -name _gen -type d -exec rm -rf \"{}\" + && sphinx-build -M html . _build --fail-on-warning", cwd = "docs", depends-on = "postinstall" } readthedocs = { cmd = "rm -rf $READTHEDOCS_OUTPUT/html && cp -r docs/_build/html $READTHEDOCS_OUTPUT/html", depends-on = "docs" } [feature.test.dependencies] From e77d6855ce073f84c56e024096d57e8da67550ab Mon Sep 17 00:00:00 2001 From: Oliver Borchert Date: Sat, 25 Oct 2025 11:06:47 +0200 Subject: [PATCH 2/5] Rename --- docs/api/filter_result/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/filter_result/index.rst b/docs/api/filter_result/index.rst index 4d4a3a89..e77519ca 100644 --- a/docs/api/filter_result/index.rst +++ b/docs/api/filter_result/index.rst @@ -1,6 +1,6 @@ -============= -Filter Result -============= +============ +FilterResult +============ .. currentmodule:: dataframely .. autosummary:: From cedf9000a8ec08630585523315f4d4672ef1e5d1 Mon Sep 17 00:00:00 2001 From: Oliver Borchert Date: Sat, 25 Oct 2025 11:11:42 +0200 Subject: [PATCH 3/5] filter and rule --- docs/api/collection/filters.rst | 10 ---------- docs/api/collection/index.rst | 1 - docs/api/collection/validation.rst | 3 +++ docs/api/schema/validation.rst | 1 + 4 files changed, 4 insertions(+), 11 deletions(-) delete mode 100644 docs/api/collection/filters.rst diff --git a/docs/api/collection/filters.rst b/docs/api/collection/filters.rst deleted file mode 100644 index 7bca0fba..00000000 --- a/docs/api/collection/filters.rst +++ /dev/null @@ -1,10 +0,0 @@ -======= -Filters -======= - -.. currentmodule:: dataframely -.. autosummary:: - :toctree: _gen/ - - require_relationship_one_to_one - require_relationship_one_to_at_least_one diff --git a/docs/api/collection/index.rst b/docs/api/collection/index.rst index 5356a85a..8c397548 100644 --- a/docs/api/collection/index.rst +++ b/docs/api/collection/index.rst @@ -11,7 +11,6 @@ Collection generation operations metadata - filters .. currentmodule:: dataframely .. autoclass:: Collection diff --git a/docs/api/collection/validation.rst b/docs/api/collection/validation.rst index 132eec19..dee716b3 100644 --- a/docs/api/collection/validation.rst +++ b/docs/api/collection/validation.rst @@ -10,3 +10,6 @@ Validation Collection.filter Collection.is_valid Collection.cast + filter + require_relationship_one_to_one + require_relationship_one_to_at_least_one diff --git a/docs/api/schema/validation.rst b/docs/api/schema/validation.rst index b8d72a6a..02c8cc66 100644 --- a/docs/api/schema/validation.rst +++ b/docs/api/schema/validation.rst @@ -10,3 +10,4 @@ Validation Schema.filter Schema.is_valid Schema.cast + rule From 6d4eb997051f49ee33bb0415280e7a06e9a521b8 Mon Sep 17 00:00:00 2001 From: Oliver Borchert Date: Sat, 25 Oct 2025 18:14:06 +0200 Subject: [PATCH 4/5] docs: Add remaining documentation for v2 --- dataframely/collection/collection.py | 8 - docs/_templates/classes/error.rst | 13 ++ docs/api/errors/index.rst | 15 ++ docs/api/index.rst | 9 + docs/conf.py | 4 +- docs/guides/features/index.md | 1 + docs/guides/features/lazy-validation.md | 41 +++++ docs/guides/index.md | 2 +- .../{versioning.md => migration/index.md} | 11 +- docs/guides/migration/v1-v2.md | 160 ++++++++++++++++++ 10 files changed, 253 insertions(+), 11 deletions(-) create mode 100644 docs/_templates/classes/error.rst create mode 100644 docs/api/errors/index.rst create mode 100644 docs/guides/features/lazy-validation.md rename docs/guides/{versioning.md => migration/index.md} (94%) create mode 100644 docs/guides/migration/v1-v2.md diff --git a/dataframely/collection/collection.py b/dataframely/collection/collection.py index 259658a0..c0c3fb88 100644 --- a/dataframely/collection/collection.py +++ b/dataframely/collection/collection.py @@ -961,11 +961,6 @@ def scan_parquet( ValueError: If the provided directory does not contain parquet files for all required members. - Note: - Due to current limitations in dataframely, this method actually reads the - parquet file into memory if `"validation"` is `"warn"` or `"allow"` - and validation is required. - Note: This method is backward compatible with older versions of dataframely in which the schema metadata was saved to `schema.json` files instead of being encoded into the parquet files. @@ -1058,9 +1053,6 @@ def scan_delta( ValueError: If the provided source does not contain Delta tables for all required members. - Note: - Due to current limitations in dataframely, this method may read the Delta table into memory if `validation` is `"warn"` or `"allow"` and validation is required. - Attention: Schema metadata is stored as custom commit metadata. Only the schema information from the last commit is used, so any table modifications diff --git a/docs/_templates/classes/error.rst b/docs/_templates/classes/error.rst new file mode 100644 index 00000000..3abb0162 --- /dev/null +++ b/docs/_templates/classes/error.rst @@ -0,0 +1,13 @@ +:html_theme.sidebar_secondary.remove: true + +.. role:: hidden + +{{ name | underline }} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ name }} + :members: + :exclude-members: add_note, with_traceback + :autosummary: + :autosummary-nosignatures: diff --git a/docs/api/errors/index.rst b/docs/api/errors/index.rst new file mode 100644 index 00000000..b1166927 --- /dev/null +++ b/docs/api/errors/index.rst @@ -0,0 +1,15 @@ +====== +Errors +====== + +.. currentmodule:: dataframely +.. autosummary:: + :toctree: _gen/ + :template: classes/error.rst + :nosignatures: + + ~exc.SchemaError + ~exc.ValidationError + ~exc.ImplementationError + ~exc.AnnotationImplementationError + ~exc.ValidationRequiredError diff --git a/docs/api/index.rst b/docs/api/index.rst index e0d5ba36..1c795da4 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -25,6 +25,15 @@ API Reference columns/index +.. grid:: + + .. grid-item-card:: + + .. toctree:: + :maxdepth: 1 + + errors/index + .. grid-item-card:: .. toctree:: diff --git a/docs/conf.py b/docs/conf.py index 56f37bed..5a358b92 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -174,7 +174,9 @@ def hide_class_signature( return_annotation: str, ) -> tuple[str, str] | None: if what == "class" and ( - name.endswith("FilterResult") or name.endswith("FailureInfo") + name.endswith("FilterResult") + or name.endswith("FailureInfo") + or name.endswith("AnnotationImplementationError") ): # Return empty signature (no args after the class name) return "", return_annotation diff --git a/docs/guides/features/index.md b/docs/guides/features/index.md index d45e62c5..f07fec42 100644 --- a/docs/guides/features/index.md +++ b/docs/guides/features/index.md @@ -8,4 +8,5 @@ data-generation primary-keys serialization sql-generation +lazy-validation ``` diff --git a/docs/guides/features/lazy-validation.md b/docs/guides/features/lazy-validation.md new file mode 100644 index 00000000..fe0e9930 --- /dev/null +++ b/docs/guides/features/lazy-validation.md @@ -0,0 +1,41 @@ +# Lazy Validation + +In many cases, dataframely's capability to validate and filter input data is used at core application boundaries. +As a result, `validate` and `filter` are generally expected to be used at points where `collect` is called on a lazy +frame. However, there may be situations where validation or filtering should simply be added to the lazy computation +graph. Starting in dataframely v2, this is supported via a custom polars plugin. + +## The `eager` parameter + +All of the following methods expose an `eager: bool` parameter: + +- {meth}`Schema.validate() ` +- {meth}`Schema.filter() ` +- {meth}`Collection.validate() ` +- {meth}`Collection.filter() ` + +By default, `eager=True`. However, users may decide to set `eager=False` in order to simply append the validation or +the filtering operation to the lazy frame. For example, one might decide to run validation lazily: + +```python +def validate_lf(lf: pl.LazyFrame) -> pl.LazyFrame: + return lf.pipe(MySchema.validate, eager=False) +``` + +When `eager=False` and the input data does not satisfy the schema, validation is only run and an error is only raised +once the lazy frame is collected. + +## Error Types + +Due to current limitations in polars plugins, the type of error that is being raised from the `validate` function (both +for schemas and collections) is dependent on the value of the `eager` parameter: + +- When `eager=True`, a {class}`~dataframely.ValidationError` is raised from the `validate` function +- When `eager=False`, a {class}`~polars.exceptions.ComputeError` is raised from the `collect` function + +```{note} +For schemas, the error _message_ itself is equivalent. +For collections, the error message for `eager=False` is limited and non-deterministic: the error message only includes +information about a single member and, if multiple members fail validation, the member that the error message refers to +may vary across executions. +``` diff --git a/docs/guides/index.md b/docs/guides/index.md index 4c25a590..d0e20ebc 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -8,7 +8,7 @@ quickstart examples/index features/index development -versioning +migration/index faq ``` diff --git a/docs/guides/versioning.md b/docs/guides/migration/index.md similarity index 94% rename from docs/guides/versioning.md rename to docs/guides/migration/index.md index 5a089759..3c06221a 100644 --- a/docs/guides/versioning.md +++ b/docs/guides/migration/index.md @@ -1,4 +1,13 @@ -# Versioning policy and breaking changes +# Migration Guides + +```{toctree} +:maxdepth: 1 +:hidden: + +v1-v2 +``` + +## Versioning policy and breaking changes Dataframely uses [semantic versioning](https://semver.org/). This versioning scheme is designed to make it easy for users to anticipate what types of change they can expect from a diff --git a/docs/guides/migration/v1-v2.md b/docs/guides/migration/v1-v2.md new file mode 100644 index 00000000..13bc5c3a --- /dev/null +++ b/docs/guides/migration/v1-v2.md @@ -0,0 +1,160 @@ +# Migrating from v1 to v2 + +Dataframely v2 introduces several improvements and some breaking changes to streamline the API. + +## Improvements + +### Lazy Validation + +Dataframely v2 finally implements lazy validation and filtering using a custom polars plugin. This allows +{meth}`Schema.validate` and {meth}`Schema.filter` to be used within lazy computation graphs instead of forcing a +`collect`. More details can be found in the [dedicated guide](../features/lazy-validation.md). + +### Lazy `scan` operations + +With lazy validation, all `scan_*` methods (e.g. {meth}`Schema.scan_parquet`, {meth}`Collection.scan_delta`, ...) are +now truly lazy, even if validation is necessary. Previously, this required collecting the input and running validation +eagerly. + +### S3 Support in all I/O functions + +Dataframely v2 now properly supports S3 for all I/O functions (i.e. `write_*`, `sink_*`, `read_*`, `scan_*`). + +## Breaking Changes + +### Columns are non-nullable by default + +In dataframely v1, specifying a column without setting the `nullable` property caused the column to be nullable and a +warning was emitted. In dataframely v2, this changes: no warning is emitted anymore and `nullable` defaults to `False`. +This mirrors the typical expectation that a column is not nullable (because `null` values often indicate issues) -- +nullability now becomes opt-in. + +### Primary keys may not be nullable + +While dataframely v1 merely emitted a warning, dataframely v2 now raises an exception if a primary key is designated +as non-nullable. This aligns dataframely, for example, with SQL where primary keys may not be nullable. + +### Schema rules are now defined as classmethods + +In order to allow schema rules to access information about the schema and, especially, information of a schema's +subclasses, schema rules must now be specified as classmethods. This means: + +```python +class MySchema(dy.Schema): + ... + + @dy.rule() + def my_rule() -> pl.Expr: + ... +``` + +turns into + +```python +class MySchema(dy.Schema): + ... + + @dy.rule() + def my_rule(cls) -> pl.Expr: + ... +``` + +Within the schema rule, `cls` can now be used to access columns or other information from the schema. Specifically, + +```python +class MySchema(dy.Schema): + a = dy.Integer() + b = dy.Integer() + + @dy.rule() + def my_rule() -> pl.Expr: + return MySchema.a.col >= MySchema.b.col +``` + +can now be written as + +```python +class MySchema(dy.Schema): + a = dy.Integer() + b = dy.Integer() + + @dy.rule() + def my_rule(cls) -> pl.Expr: + return cls.a.col >= cls.b.col +``` + +If you are using [ruff](https://docs.astral.sh/ruff/), you will need to add the following to your `pyproject.toml` for +`ruff` to recognize `@dy.rule` as a decorator that turns a method into a classmethod: + +```toml +[tool.ruff.lint.pep8-naming] +classmethod-decorators = ["dataframely.rule"] +``` + +### Predefined checks for floats are updated + +For floating point types ({class}`~dataframely.Float`, {class}`~dataframely.Float32`, {class}`~dataframely.Float64`), +the `allow_inf_nan` option has been split into `allow_inf` and `allow_nan`, allowing to set these to be set +independently. Note that the defaults remain the same, i.e., if `allow_inf_nan` wasn't set before, nothing changes. + +### Schema conversion functions are renamed + +The methods that allow converting a dataframely {class}`~dataframely.Schema` into a schema of another package have been +renamed to better align with the naming scheme of conversion functions in other packages: + +- `sql_schema` → `to_sqlalchemy_columns` +- `pyarrow_schema` → `to_pyarrow_schema` +- `polars_schema` → `to_polars_schema` + +### Methods related to primary keys are renamed + +When talking about the "primary key" of a schema, a primary key may span multiple columns, yet, it is still a single +(composite) primary key. To align with this notion in the code, we rename primary key-related methods: + +- `Schema.primary_keys` → `Schema.primary_key` +- `Collection.common_primary_keys` → `Collection.common_primary_key` + +### Utility functions for collection filters are renamed and safer + +For writing collection filters, dataframely exposes two utility functions to express the `1:1` and `1:{1,N}` +relationships between members. These have been renamed as follows: + +- `filter_relationship_one_to_one` → `require_relationship_one_to_one` +- `filter_relationship_one_to_at_least_one` → `require_relationship_one_to_at_least_one` + +Additionally, their behavior changes: even if primary key constraints are not enforced on the schema, the method +now behaves correctly. Previously, the validation result could duplicate input rows. + +If the relationships are already enforced by primary key constraints on the schemas[^1], you can still specify +`drop_duplicates=False`. This returns to the previous behavior and allows for considerable performance improvements. + +To return to the previous behavior and benefit from the, you can still specify `drop_duplicates=False`. + +[^1]: This is often the case if the filter's purpose is to remove rows that exist in one member but not the other. + +### Collection metadata cannot be read from `schema.json` anymore + +Prior to dataframely v1.8.0, collection metadata has been serialized as a `schema.json` file when calling +`write_parquet` or `scan_parquet` on a collection. Since dataframely v1.8.0, the metadata has been moved to the +individual members' parquet metadata. + +While dataframely v1 still supported reading the metadata from collections written with a version of dataframely prior +to v1.8.0, dataframely v2 removes this support. + +### The mypy plugin is removed entirely + +The mypy plugin in dataframely v1 had two purposes: + +- Ensure that a method with `@dy.rule` decorator is recognized as a rule +- Turn non-specific return types into ones with enriched type information (e.g. `dict` → `TypedDict`) + +Unfortunately, the latter was error-prone as it yielded many false positives and generally made working with these +types less ergonomic. We therefore actively removed this part. With `@dy.rule` being applied to classmethods, the need +for a custom mypy plugin is eliminated entirely. As a result, `dataframely.mypy` has been removed. + +If you have used the mypy plugin before, you can remove the following from your `pyproject.toml`: + +```toml +[tool.mypy] +plugins = ["dataframely.mypy"] +``` From bb7d9ac170ebaefdd0afedb37dbf160fdcd8f5d5 Mon Sep 17 00:00:00 2001 From: Oliver Borchert Date: Mon, 27 Oct 2025 10:45:45 -0700 Subject: [PATCH 5/5] Review --- docs/guides/faq.md | 17 +++++++++++++++++ docs/guides/features/lazy-validation.md | 4 ++-- docs/guides/migration/v1-v2.md | 11 ++++++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/guides/faq.md b/docs/guides/faq.md index 2a02d064..e7dfc90f 100644 --- a/docs/guides/faq.md +++ b/docs/guides/faq.md @@ -29,3 +29,20 @@ class UserSchema(dy.Schema): """Email must be unique, if provided.""" return pl.col("email").is_null() | pl.col("email").is_unique() ``` + +## How do I fix the ruff error `First argument of a method should be named self`? + +If you are using [`ruff`](https://docs.astral.sh/ruff/) and introduce custom rules for your schemas, `ruff` will create +the following linting error: + +``` +N805 First argument of a method should be named `self` +``` + +To fix this, you'll need to let `ruff` know that the `@dy.rule` decorator is applied to classmethods. This can easily +be done by adding the following to your `pyproject.toml`: + +```toml +[tool.ruff.lint.pep8-naming] +classmethod-decorators = ["dataframely.rule"] +``` diff --git a/docs/guides/features/lazy-validation.md b/docs/guides/features/lazy-validation.md index fe0e9930..6c9edbe7 100644 --- a/docs/guides/features/lazy-validation.md +++ b/docs/guides/features/lazy-validation.md @@ -22,8 +22,8 @@ def validate_lf(lf: pl.LazyFrame) -> pl.LazyFrame: return lf.pipe(MySchema.validate, eager=False) ``` -When `eager=False` and the input data does not satisfy the schema, validation is only run and an error is only raised -once the lazy frame is collected. +When `eager=False`, validation is only run once the lazy frame is collected. If input data does not satisfy the schema, +no error is raised here, yet. ## Error Types diff --git a/docs/guides/migration/v1-v2.md b/docs/guides/migration/v1-v2.md index 13bc5c3a..7645f1f4 100644 --- a/docs/guides/migration/v1-v2.md +++ b/docs/guides/migration/v1-v2.md @@ -29,10 +29,10 @@ warning was emitted. In dataframely v2, this changes: no warning is emitted anym This mirrors the typical expectation that a column is not nullable (because `null` values often indicate issues) -- nullability now becomes opt-in. -### Primary keys may not be nullable +### Primary key columns may not be nullable While dataframely v1 merely emitted a warning, dataframely v2 now raises an exception if a primary key is designated -as non-nullable. This aligns dataframely, for example, with SQL where primary keys may not be nullable. +as non-nullable. This aligns dataframely, for example, with SQL where primary key columns may not be nullable. ### Schema rules are now defined as classmethods @@ -83,6 +83,7 @@ class MySchema(dy.Schema): return cls.a.col >= cls.b.col ``` +To migrate your existing code without changing behavior, simply add the `cls` argument to the signature of your rules. If you are using [ruff](https://docs.astral.sh/ruff/), you will need to add the following to your `pyproject.toml` for `ruff` to recognize `@dy.rule` as a decorator that turns a method into a classmethod: @@ -128,8 +129,6 @@ now behaves correctly. Previously, the validation result could duplicate input r If the relationships are already enforced by primary key constraints on the schemas[^1], you can still specify `drop_duplicates=False`. This returns to the previous behavior and allows for considerable performance improvements. -To return to the previous behavior and benefit from the, you can still specify `drop_duplicates=False`. - [^1]: This is often the case if the filter's purpose is to remove rows that exist in one member but not the other. ### Collection metadata cannot be read from `schema.json` anymore @@ -139,7 +138,9 @@ Prior to dataframely v1.8.0, collection metadata has been serialized as a `schem individual members' parquet metadata. While dataframely v1 still supported reading the metadata from collections written with a version of dataframely prior -to v1.8.0, dataframely v2 removes this support. +to v1.8.0, dataframely v2 removes this support. If you still have data written with a version of dataframely earlier +than v1.8.0, and, thus, still have `schema.json` files, you can migrate your data by reading it and writing it back to +disk with any version of dataframely `>=1.8.0,<2`. ### The mypy plugin is removed entirely