diff --git a/dataframely/_compat.py b/dataframely/_compat.py index 60e3349c..7fe418a0 100644 --- a/dataframely/_compat.py +++ b/dataframely/_compat.py @@ -80,10 +80,14 @@ class Dialect: # type: ignore # noqa: N801 from polars._typing import ( # type: ignore[attr-defined,unused-ignore] PartitioningScheme as PartitionSchemeOrSinkDirectory, ) -else: +elif _polars_version_tuple < (1, 38): # pragma: no cover from polars.io.partition import ( # type: ignore[no-redef,attr-defined,unused-ignore] _SinkDirectory as PartitionSchemeOrSinkDirectory, ) +else: + from polars.io.partition import ( # type: ignore[no-redef,attr-defined,unused-ignore] + PartitionBy as PartitionSchemeOrSinkDirectory, + ) # ------------------------------------------------------------------------------------ # diff --git a/dataframely/_storage/__init__.py b/dataframely/_storage/__init__.py index 780ec798..25528ddc 100644 --- a/dataframely/_storage/__init__.py +++ b/dataframely/_storage/__init__.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: BSD-3-Clause from ._base import StorageBackend +from ._fsspec import get_file_prefix -__all__ = [ - "StorageBackend", -] +__all__ = ["StorageBackend", "get_file_prefix"] diff --git a/dataframely/_storage/_fsspec.py b/dataframely/_storage/_fsspec.py new file mode 100644 index 00000000..e0aa3a4a --- /dev/null +++ b/dataframely/_storage/_fsspec.py @@ -0,0 +1,18 @@ +# Copyright (c) QuantCo 2025-2026 +# SPDX-License-Identifier: BSD-3-Clause + +from fsspec import AbstractFileSystem + + +def get_file_prefix(fs: AbstractFileSystem) -> str: + match fs.protocol: + case "file": + return "" + case str(): + return f"{fs.protocol}://" + case ["file", *_]: + return "" + case [str(proto), *_]: + return f"{proto}://" + case _: + raise ValueError(f"Unexpected fs.protocol: {fs.protocol}") diff --git a/dataframely/_storage/parquet.py b/dataframely/_storage/parquet.py index fc8ba46c..655c5956 100644 --- a/dataframely/_storage/parquet.py +++ b/dataframely/_storage/parquet.py @@ -7,6 +7,8 @@ import polars as pl from fsspec import AbstractFileSystem, url_to_fs +from dataframely._storage import get_file_prefix + from ._base import ( SerializedCollection, SerializedRules, @@ -79,7 +81,9 @@ def sink_collection( fs: AbstractFileSystem = url_to_fs(path)[0] for key, lf in dfs.items(): destination = ( - fs.sep.join([path, key]) + # Enforce that the path ends with a separator. Otherwise + # polars misbehaves on Windows. + fs.sep.join([path, key]) + fs.sep if "partition_by" in kwargs else fs.sep.join([path, f"{key}.parquet"]) ) @@ -107,7 +111,9 @@ def write_collection( fs: AbstractFileSystem = url_to_fs(path)[0] for key, lf in dfs.items(): destination = ( - fs.sep.join([path, key]) + # Enforce that the path ends with a separator. Otherwise + # polars misbehaves on Windows. + fs.sep.join([path, key]) + fs.sep if "partition_by" in kwargs else fs.sep.join([path, f"{key}.parquet"]) ) @@ -155,15 +161,7 @@ def _collection_from_parquet( if is_file: collection_types.append(_read_serialized_collection(source_path)) else: - prefix = ( - "" - if fs.protocol == "file" - else ( - f"{fs.protocol}://" - if isinstance(fs.protocol, str) - else f"{fs.protocol[0]}://" - ) - ) + prefix = get_file_prefix(fs) for file in fs.glob(fs.sep.join([source_path, "**", "*.parquet"])): collection_types.append( _read_serialized_collection(f"{prefix}{file}") diff --git a/dataframely/testing/storage.py b/dataframely/testing/storage.py index e5f15593..e09c2477 100644 --- a/dataframely/testing/storage.py +++ b/dataframely/testing/storage.py @@ -10,6 +10,7 @@ import dataframely as dy from dataframely import FailureInfo, Validation from dataframely._compat import deltalake +from dataframely._storage import get_file_prefix from dataframely._storage.delta import _to_delta_table # ----------------------------------- Schema ------------------------------------------- @@ -190,19 +191,7 @@ def set_metadata(self, path: str, metadata: dict[str, Any]) -> None: metadata.""" def _prefix_path(self, path: str, fs: AbstractFileSystem) -> str: - return f"{self._get_prefix(fs)}{path}" - - @staticmethod - def _get_prefix(fs: AbstractFileSystem) -> str: - return ( - "" - if fs.protocol == "file" - else ( - f"{fs.protocol}://" - if isinstance(fs.protocol, str) - else f"{fs.protocol[0]}://" - ) - ) + return f"{get_file_prefix(fs)}{path}" class ParquetCollectionStorageTester(CollectionStorageTester): diff --git a/pixi.lock b/pixi.lock index d0cd283f..06db5af4 100644 --- a/pixi.lock +++ b/pixi.lock @@ -3,8 +3,6 @@ environments: build: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -450,8 +448,6 @@ environments: default: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -666,8 +662,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-hooks-5.0.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/prettier-3.8.1-h7e4c9f4_0.conda @@ -979,8 +975,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.36.1-py310hff09b76_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.38.0-py310hff09b76_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-hooks-5.0.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/prettier-3.8.1-h1e5041c_0.conda @@ -1288,8 +1284,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.36.1-py310hfb6bc98_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.38.0-py310had17480_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-hooks-5.0.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/prettier-3.8.1-h07b0e94_0.conda @@ -1598,8 +1594,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.36.1-py310h34bb384_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.38.0-py310haaaf75b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-hooks-5.0.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/prettier-3.8.1-h9907cc9_0.conda @@ -1888,8 +1884,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.36.1-py310hca7251b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.38.0-py310hca7251b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-hooks-5.0.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/prettier-3.8.1-hc95d2ff_0.conda @@ -1996,8 +1992,6 @@ environments: default-polars-minimal: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -3542,8 +3536,6 @@ environments: docs: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -4345,8 +4337,6 @@ environments: lint: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -4673,8 +4663,6 @@ environments: nightly: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -5681,8 +5669,6 @@ environments: polars-minimal: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -6363,8 +6349,6 @@ environments: py310: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -6455,8 +6439,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/propcache-0.3.1-py310h89163eb_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py310h139afa4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -6596,8 +6580,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.36.1-py310hff09b76_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.38.0-py310hff09b76_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/propcache-0.3.1-py310heeae437_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/psutil-7.2.2-py310hef25091_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -6731,8 +6715,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.36.1-py310hfb6bc98_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.38.0-py310had17480_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/propcache-0.3.1-py310h8e2f543_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py310h8bcfd8d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -6867,8 +6851,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.36.1-py310h34bb384_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.38.0-py310haaaf75b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/propcache-0.3.1-py310hc74094e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py310haea493c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -7000,8 +6984,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.36.1-py310hca7251b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.38.0-py310hca7251b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/propcache-0.3.1-py310h38315fa_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py310h1637853_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -7060,8 +7044,6 @@ environments: py311: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -7151,8 +7133,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/propcache-0.3.1-py311h2dc5d0c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -7288,8 +7270,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.36.1-py310hff09b76_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.38.0-py310hff09b76_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/propcache-0.3.1-py311h58d527c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/psutil-7.2.2-py311h51cfe5d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -7419,8 +7401,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.36.1-py310hfb6bc98_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.38.0-py310had17480_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/propcache-0.3.1-py311ha3cf9ac_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py311ha332486_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -7551,8 +7533,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.36.1-py310h34bb384_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.38.0-py310haaaf75b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/propcache-0.3.1-py311h4921393_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py311he363849_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -7680,8 +7662,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.36.1-py310hca7251b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.38.0-py310hca7251b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/propcache-0.3.1-py311h5082efb_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py311hf893f09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -7738,8 +7720,6 @@ environments: py312: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -7829,8 +7809,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/propcache-0.3.1-py312h178313f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py312h5253ce2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -7966,8 +7946,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.36.1-py310hff09b76_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.38.0-py310hff09b76_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/propcache-0.3.1-py312hcc812fe_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/psutil-7.2.2-py312hd41f8a7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -8097,8 +8077,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.36.1-py310hfb6bc98_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.38.0-py310had17480_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/propcache-0.3.1-py312h3520af0_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py312hf7082af_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -8229,8 +8209,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.36.1-py310h34bb384_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.38.0-py310haaaf75b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/propcache-0.3.1-py312h998013c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py312hb3ab3e3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -8358,8 +8338,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh8b19718_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.36.1-py310hca7251b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.38.0-py310hca7251b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/propcache-0.3.1-py312h31fea79_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py312he5662c2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -8416,8 +8396,6 @@ environments: py313: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -8505,8 +8483,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/propcache-0.3.1-py313h8060acc_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py313h54dd161_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -8639,8 +8617,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.36.1-py310hff09b76_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.38.0-py310hff09b76_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/propcache-0.3.1-py313h857f82b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/psutil-7.2.2-py313h62ef0ea_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -8770,8 +8748,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.36.1-py310hfb6bc98_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.38.0-py310had17480_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/propcache-0.3.1-py313h717bdf5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py313h16366db_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -8902,8 +8880,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.36.1-py310h34bb384_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.38.0-py310haaaf75b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/propcache-0.3.1-py313ha9b7d5b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py313h6688731_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -9031,8 +9009,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.36.1-py310hca7251b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.38.0-py310hca7251b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/propcache-0.3.1-py313hb4c8b1a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py313h5fd188c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -9088,8 +9066,6 @@ environments: py314: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -9178,8 +9154,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py314h0f05182_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -9314,8 +9290,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.36.1-py310hff09b76_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.38.0-py310hff09b76_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/psutil-7.2.2-py314h2e8dab5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -9447,8 +9423,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.36.1-py310hfb6bc98_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.38.0-py310had17480_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py314hd330473_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -9581,8 +9557,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.36.1-py310h34bb384_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.38.0-py310haaaf75b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py314ha14b1ff_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -9712,8 +9688,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.36.1-py310hca7251b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.38.0-py310hca7251b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py314hc5dbbe4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -9770,8 +9746,6 @@ environments: py314-optionals: channels: - url: https://conda.anaconda.org/conda-forge/ - options: - pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -9920,8 +9894,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py314h0f05182_0.conda @@ -10127,8 +10101,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.36.1-py310hff09b76_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.38.0-py310hff09b76_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/prometheus-cpp-1.3.0-h7938499_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/psutil-7.2.2-py314h2e8dab5_0.conda @@ -10328,8 +10302,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.36.1-py310hfb6bc98_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.38.0-py310had17480_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/prometheus-cpp-1.3.0-h7802330_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-7.2.2-py314hd330473_0.conda @@ -10529,8 +10503,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.36.1-py310h34bb384_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.38.0-py310haaaf75b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/prometheus-cpp-1.3.0-h0967b3e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-7.2.2-py314ha14b1ff_0.conda @@ -10713,8 +10687,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.36.1-py310hca7251b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.38.0-py310hca7251b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/propcache-0.3.1-pyhe1237c8_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-7.2.2-py314hc5dbbe4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_1.conda @@ -23875,11 +23849,11 @@ packages: license_family: MIT size: 513921 timestamp: 1763738199817 -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda - sha256: 8a6bcee3c0a0dc00a880082dbcb18f2ca619f9a7ac1a10e91126a06b2e413efb - md5: 160b41862a43936cbe509d1879d67f54 +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda + sha256: 06f66ea42ec3d2dd18a1529208e45e8d580b5d49bff7779166fb2ba24380c8d3 + md5: 1894d4373da653406c91e20ef89f05c8 depends: - - polars-runtime-32 ==1.36.1 + - polars-runtime-32 ==1.37.1 - python >=3.10 - python constrains: @@ -23893,18 +23867,18 @@ packages: - pyiceberg >=0.7.1 - altair >=5.4.0 - great_tables >=0.8.0 - - polars-runtime-32 ==1.36.1 - - polars-runtime-64 ==1.36.1 - - polars-runtime-compat ==1.36.1 + - polars-runtime-32 ==1.37.1 + - polars-runtime-64 ==1.37.1 + - polars-runtime-compat ==1.37.1 license: MIT license_family: MIT - size: 522848 - timestamp: 1765344520067 -- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda - sha256: 06f66ea42ec3d2dd18a1529208e45e8d580b5d49bff7779166fb2ba24380c8d3 - md5: 1894d4373da653406c91e20ef89f05c8 + size: 524697 + timestamp: 1768304090323 +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda + sha256: 8c8981d805d27b7d0c9fbb9b26ad42e62170a657d3dd1e3711fd62dd39f653a1 + md5: d9f44a3b02ff198d40562d05e758ad03 depends: - - polars-runtime-32 ==1.37.1 + - polars-runtime-32 ==1.38.0 - python >=3.10 - python constrains: @@ -23918,13 +23892,12 @@ packages: - pyiceberg >=0.7.1 - altair >=5.4.0 - great_tables >=0.8.0 - - polars-runtime-32 ==1.37.1 - - polars-runtime-64 ==1.37.1 - - polars-runtime-compat ==1.37.1 + - polars-runtime-32 ==1.38.0 + - polars-runtime-64 ==1.38.0 + - polars-runtime-compat ==1.38.0 license: MIT - license_family: MIT - size: 524697 - timestamp: 1768304090323 + size: 525234 + timestamp: 1770222326549 - conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.35.2-py310hffdcd12_0.conda noarch: python sha256: a2294d8079173544b519e1564ce4897dc176b92dbba9508c75c42e8cba6fe680 @@ -23942,10 +23915,10 @@ packages: license_family: MIT size: 33271651 timestamp: 1763738199812 -- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.1-py310hffdcd12_0.conda noarch: python - sha256: 53f3cbe0ce39f7e21e64b9a1f61abf6353c679f575a47fe72715d0cf02319e54 - md5: af35229f34c80dcfab5a40414440df23 + sha256: 275a845cf713a33bc6634f6773541be16868b333222d8e200c7ecd1dbd07c218 + md5: 732a536c6ce768f096f5340121e10cc5 depends: - python - __glibc >=2.17,<3.0.a0 @@ -23957,25 +23930,24 @@ packages: - __glibc >=2.17 license: MIT license_family: MIT - size: 35250145 - timestamp: 1765344520066 -- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.1-py310hffdcd12_0.conda + size: 35782067 + timestamp: 1768304090321 +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda noarch: python - sha256: 275a845cf713a33bc6634f6773541be16868b333222d8e200c7ecd1dbd07c218 - md5: 732a536c6ce768f096f5340121e10cc5 + sha256: 9223859b0ce03a244ab3a33431b05e4e1e072b951e7759e8189f0aac6ab160d1 + md5: 55bba24eb42fccab68125573fe3e702e depends: - python + - libgcc >=14 - __glibc >=2.17,<3.0.a0 - libstdcxx >=14 - - libgcc >=14 - _python_abi3_support 1.* - cpython >=3.10 constrains: - __glibc >=2.17 license: MIT - license_family: MIT - size: 35782067 - timestamp: 1768304090321 + size: 35494523 + timestamp: 1770222326547 - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.35.2-py310hff09b76_0.conda noarch: python sha256: 8b88e1e02b04362d58cbd7f599a1c5c8ceb43fd63c51279a76b92d5f8e65d0fd @@ -23992,26 +23964,26 @@ packages: license_family: MIT size: 30689142 timestamp: 1763738129075 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.36.1-py310hff09b76_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.37.1-py310hff09b76_0.conda noarch: python - sha256: 6f27ee594bc9947e21affa5e2ad00f93045c624b8db430ffb06ad57d5efc590f - md5: c282f5e96f8ca8ea0b58aa10e8d99f06 + sha256: f63db1ec9c7bd6e8aa26e535a7e8c70dccb87fa40241976a1fc74862b6c1b8f0 + md5: 7c11ec4620b57eb6ab9d1ba930f9acdc depends: - python - - libstdcxx >=14 - libgcc >=14 + - libstdcxx >=14 - _python_abi3_support 1.* - cpython >=3.10 constrains: - __glibc >=2.17 license: MIT license_family: MIT - size: 32541394 - timestamp: 1765344542517 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.37.1-py310hff09b76_0.conda + size: 33051868 + timestamp: 1768304072067 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.38.0-py310hff09b76_0.conda noarch: python - sha256: f63db1ec9c7bd6e8aa26e535a7e8c70dccb87fa40241976a1fc74862b6c1b8f0 - md5: 7c11ec4620b57eb6ab9d1ba930f9acdc + sha256: f3cac00420b055f39549ca6a46160e3ca406ebad411009432433f2c210153644 + md5: 8e31b221427a04c05624d5e89b373e0c depends: - python - libgcc >=14 @@ -24021,9 +23993,8 @@ packages: constrains: - __glibc >=2.17 license: MIT - license_family: MIT - size: 33051868 - timestamp: 1768304072067 + size: 32991302 + timestamp: 1770222341285 - conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.35.2-py310hfb6bc98_0.conda noarch: python sha256: 0beeea67b3a4e868bd2e9cf2a6085e62a0d753dbd78d264d5b1afce1bccc2e84 @@ -24040,10 +24011,10 @@ packages: license_family: MIT size: 32990949 timestamp: 1763738019221 -- conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.36.1-py310hfb6bc98_0.conda +- conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.37.1-py310had17480_0.conda noarch: python - sha256: 3ab320a6175732165f9e14c447ab766e221322bb0c74c78b4eab8b60246c7032 - md5: a466731fdecd70299823349a913731c2 + sha256: d1ef07dfe8647173d31165de5943be447d9da4b7a8956ebbd99b6dea2a3c1951 + md5: 75e808381cab0c33008317fd25ba8157 depends: - python - libcxx >=19 @@ -24054,12 +24025,12 @@ packages: - __osx >=10.13 license: MIT license_family: MIT - size: 34227518 - timestamp: 1765344423449 -- conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.37.1-py310had17480_0.conda + size: 35492736 + timestamp: 1768303924189 +- conda: https://conda.anaconda.org/conda-forge/osx-64/polars-runtime-32-1.38.0-py310had17480_0.conda noarch: python - sha256: d1ef07dfe8647173d31165de5943be447d9da4b7a8956ebbd99b6dea2a3c1951 - md5: 75e808381cab0c33008317fd25ba8157 + sha256: 3bb3b212765275943f8a42a05c07d45a10e6c5a2048d4e3a9c4fed4966d71f13 + md5: f56bc2c3eb5a827a4bb901b840565773 depends: - python - libcxx >=19 @@ -24069,9 +24040,8 @@ packages: constrains: - __osx >=10.13 license: MIT - license_family: MIT - size: 35492736 - timestamp: 1768303924189 + size: 35862455 + timestamp: 1770222292049 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.35.2-py310h34bb384_0.conda noarch: python sha256: 3f1b00a0ee4e56edfe272d60d51b3c243abeb1e0f872288182ef82d60f7c0d7b @@ -24088,10 +24058,10 @@ packages: license_family: MIT size: 30029154 timestamp: 1763738030442 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.36.1-py310h34bb384_0.conda +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.37.1-py310haaaf75b_0.conda noarch: python - sha256: e9ab1c2833fc368bcbc27c214cbc5123f16cb243dfcb07aaf0bc060638a17ea0 - md5: 4cc0693aae853723df55150875a2d602 + sha256: 1c79affdb6f0fcb466d1116ebeb56edb57510549f87351550a6f96f2211d5d2b + md5: bb3c5484e1c5376846e1b406fd63a3c4 depends: - python - __osx >=11.0 @@ -24102,24 +24072,23 @@ packages: - __osx >=11.0 license: MIT license_family: MIT - size: 31508688 - timestamp: 1765344479373 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.37.1-py310haaaf75b_0.conda + size: 32229626 + timestamp: 1768303983463 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/polars-runtime-32-1.38.0-py310haaaf75b_0.conda noarch: python - sha256: 1c79affdb6f0fcb466d1116ebeb56edb57510549f87351550a6f96f2211d5d2b - md5: bb3c5484e1c5376846e1b406fd63a3c4 + sha256: 74cdbb113a4cb011b1eeb9f732cf994e1360a9c9d5fbc5b3e59a43ee8261c952 + md5: 8b597d04fb4ff61cb1a1aa2dedf20927 depends: - python - - __osx >=11.0 - libcxx >=19 + - __osx >=11.0 - _python_abi3_support 1.* - cpython >=3.10 constrains: - __osx >=11.0 license: MIT - license_family: MIT - size: 32229626 - timestamp: 1768303983463 + size: 32463915 + timestamp: 1770222213396 - conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.35.2-py310hca7251b_0.conda noarch: python sha256: 03fcd84f828086be2cf658fb6250dfa665da241900f61326cae4c5d8c49642b7 @@ -24138,10 +24107,10 @@ packages: license_family: MIT size: 36375197 timestamp: 1763738028556 -- conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.36.1-py310hca7251b_0.conda +- conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.37.1-py310hca7251b_0.conda noarch: python - sha256: 8def44d2158c55bb3bd604f7744d18aef21242e487aececabb2bd14aa3b57716 - md5: 1938c5ab40c1343a779973871b2ee04d + sha256: 34db578b4bae3ec365ff846c1f01b2720ab01d202e4fc6826114070673e6aeb0 + md5: 910a4338c2ff9b850374c16fe081b1c3 depends: - python - vc >=14.3,<15 @@ -24151,12 +24120,12 @@ packages: - cpython >=3.10 license: MIT license_family: MIT - size: 38501800 - timestamp: 1765344443861 -- conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.37.1-py310hca7251b_0.conda + size: 39228824 + timestamp: 1768303964523 +- conda: https://conda.anaconda.org/conda-forge/win-64/polars-runtime-32-1.38.0-py310hca7251b_0.conda noarch: python - sha256: 34db578b4bae3ec365ff846c1f01b2720ab01d202e4fc6826114070673e6aeb0 - md5: 910a4338c2ff9b850374c16fe081b1c3 + sha256: 4ca783286658ef0f6249cb0d069fa246c5635eea5029f8acf88b6cc557b584d8 + md5: ebf071ad99f66fce0a4f75bebceba448 depends: - python - vc >=14.3,<15 @@ -24165,9 +24134,8 @@ packages: - _python_abi3_support 1.* - cpython >=3.10 license: MIT - license_family: MIT - size: 39228824 - timestamp: 1768303964523 + size: 39410095 + timestamp: 1770222241295 - conda: https://conda.anaconda.org/conda-forge/noarch/pre-commit-4.5.1-pyha770c72_0.conda sha256: 5b81b7516d4baf43d0c185896b245fa7384b25dc5615e7baa504b7fa4e07b706 md5: 7f3ac694319c7eaf81a0325d6405e974 diff --git a/pixi.toml b/pixi.toml index 71fcf516..855b3bc3 100644 --- a/pixi.toml +++ b/pixi.toml @@ -117,35 +117,35 @@ polars = "1.35.*" [feature.polars-latest.dependencies] # NOTE: Update docs/faq.md when updating this. -polars = "1.36.*" +polars = "1.38.*" [feature.nightly.tasks] install-polars-nightly = "pip install --pre --no-deps --upgrade --only-binary :all: polars polars-runtime-32" [environments] build = ["build"] -default = ["dev", "lint", "optionals", "py314", "test", "polars-latest"] +default = ["dev", "lint", "optionals", "polars-latest", "py314", "test"] docs = ["docs"] lint = { features = ["lint"], no-default-feature = true } nightly = ["nightly", "optionals", "test"] # Different python versions with the latest polars -py310 = ["py310", "test", "polars-latest"] -py311 = ["py311", "test", "polars-latest"] -py312 = ["py312", "test", "polars-latest"] -py313 = ["py313", "test", "polars-latest"] -py314 = ["py314", "test", "polars-latest"] +py310 = ["polars-latest", "py310", "test"] +py311 = ["polars-latest", "py311", "test"] +py312 = ["polars-latest", "py312", "test"] +py313 = ["polars-latest", "py313", "test"] +py314 = ["polars-latest", "py314", "test"] # Test with optional dependencies -py314-optionals = ["optionals", "py314", "test", "polars-latest"] +py314-optionals = ["optionals", "polars-latest", "py314", "test"] # Polars compatibility envs -polars-minimal = ["py314", "test", "polars-minimal"] default-polars-minimal = [ "dev", "lint", "optionals", + "polars-minimal", "py314", "test", - "polars-minimal", ] +polars-minimal = ["polars-minimal", "py314", "test"] diff --git a/tests/storage/test_fsspec.py b/tests/storage/test_fsspec.py new file mode 100644 index 00000000..4e0d4a75 --- /dev/null +++ b/tests/storage/test_fsspec.py @@ -0,0 +1,26 @@ +# Copyright (c) QuantCo 2025-2026 +# SPDX-License-Identifier: BSD-3-Clause + +from typing import Any + +import pytest + +from dataframely._storage._fsspec import get_file_prefix + + +class MockFS: + def __init__(self, protocol: Any) -> None: + self.protocol = protocol + + +def test_get_file_prefix() -> None: + assert get_file_prefix(MockFS("file")) == "" + assert get_file_prefix(MockFS("s3")) == "s3://" + assert get_file_prefix(MockFS(["file", "whatever"])) == "" + assert get_file_prefix(MockFS(["s3", "whatever"])) == "s3://" + + +@pytest.mark.parametrize("protocol", [5, None, [5]]) +def test_get_file_prefix_invalid(protocol: Any) -> None: + with pytest.raises(ValueError): + assert 1 == get_file_prefix(MockFS(protocol))