Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- bioagent-bench/.venv/lib/python3.14/site-packages/attr/_version_info.py +89 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/filesystems/__init__.py +47 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/__init__.py +136 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/formatting.py +678 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/jax_formatter.py +174 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/np_formatter.py +120 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/polars_formatter.py +124 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/tf_formatter.py +129 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/torch_formatter.py +130 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/abc.py +53 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/generator.py +62 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/parquet.py +159 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/spark.py +57 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/text.py +58 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/arrow/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/arrow/arrow.py +77 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/audiofolder/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/audiofolder/audiofolder.py +86 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/cache/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/cache/cache.py +195 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/eval/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/eval/eval.py +77 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/hdf5/hdf5.py +389 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/json/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/json/json.py +383 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/lance/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/lance/lance.py +235 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/niftifolder/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/niftifolder/niftifolder.py +23 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/parquet/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/parquet/parquet.py +217 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/spark/spark.py +367 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/text/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/text/text.py +137 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/webdataset/__init__.py +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/webdataset/_tenbin.py +285 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/webdataset/webdataset.py +349 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/parallel/__init__.py +1 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/datasets/parallel/parallel.py +120 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/INSTALLER +1 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/LICENSE +35 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/METADATA +281 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/RECORD +56 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/REQUESTED +0 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/WHEEL +5 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/top_level.txt +1 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/pandas/__init__.py +353 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/pandas/_typing.py +578 -0
- bioagent-bench/.venv/lib/python3.14/site-packages/pandas/_version.py +692 -0
bioagent-bench/.venv/lib/python3.14/site-packages/attr/_version_info.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: MIT
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
from functools import total_ordering
|
| 5 |
+
|
| 6 |
+
from ._funcs import astuple
|
| 7 |
+
from ._make import attrib, attrs
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
@total_ordering
|
| 11 |
+
@attrs(eq=False, order=False, slots=True, frozen=True)
|
| 12 |
+
class VersionInfo:
|
| 13 |
+
"""
|
| 14 |
+
A version object that can be compared to tuple of length 1--4:
|
| 15 |
+
|
| 16 |
+
>>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2)
|
| 17 |
+
True
|
| 18 |
+
>>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1)
|
| 19 |
+
True
|
| 20 |
+
>>> vi = attr.VersionInfo(19, 2, 0, "final")
|
| 21 |
+
>>> vi < (19, 1, 1)
|
| 22 |
+
False
|
| 23 |
+
>>> vi < (19,)
|
| 24 |
+
False
|
| 25 |
+
>>> vi == (19, 2,)
|
| 26 |
+
True
|
| 27 |
+
>>> vi == (19, 2, 1)
|
| 28 |
+
False
|
| 29 |
+
|
| 30 |
+
.. versionadded:: 19.2
|
| 31 |
+
"""
|
| 32 |
+
|
| 33 |
+
year = attrib(type=int)
|
| 34 |
+
minor = attrib(type=int)
|
| 35 |
+
micro = attrib(type=int)
|
| 36 |
+
releaselevel = attrib(type=str)
|
| 37 |
+
|
| 38 |
+
@classmethod
|
| 39 |
+
def _from_version_string(cls, s):
|
| 40 |
+
"""
|
| 41 |
+
Parse *s* and return a _VersionInfo.
|
| 42 |
+
"""
|
| 43 |
+
v = s.split(".")
|
| 44 |
+
if len(v) == 3:
|
| 45 |
+
v.append("final")
|
| 46 |
+
|
| 47 |
+
return cls(
|
| 48 |
+
year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3]
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
def _ensure_tuple(self, other):
|
| 52 |
+
"""
|
| 53 |
+
Ensure *other* is a tuple of a valid length.
|
| 54 |
+
|
| 55 |
+
Returns a possibly transformed *other* and ourselves as a tuple of
|
| 56 |
+
the same length as *other*.
|
| 57 |
+
"""
|
| 58 |
+
|
| 59 |
+
if self.__class__ is other.__class__:
|
| 60 |
+
other = astuple(other)
|
| 61 |
+
|
| 62 |
+
if not isinstance(other, tuple):
|
| 63 |
+
raise NotImplementedError
|
| 64 |
+
|
| 65 |
+
if not (1 <= len(other) <= 4):
|
| 66 |
+
raise NotImplementedError
|
| 67 |
+
|
| 68 |
+
return astuple(self)[: len(other)], other
|
| 69 |
+
|
| 70 |
+
def __eq__(self, other):
|
| 71 |
+
try:
|
| 72 |
+
us, them = self._ensure_tuple(other)
|
| 73 |
+
except NotImplementedError:
|
| 74 |
+
return NotImplemented
|
| 75 |
+
|
| 76 |
+
return us == them
|
| 77 |
+
|
| 78 |
+
def __lt__(self, other):
|
| 79 |
+
try:
|
| 80 |
+
us, them = self._ensure_tuple(other)
|
| 81 |
+
except NotImplementedError:
|
| 82 |
+
return NotImplemented
|
| 83 |
+
|
| 84 |
+
# Since alphabetically "dev0" < "final" < "post1" < "post2", we don't
|
| 85 |
+
# have to do anything special with releaselevel for now.
|
| 86 |
+
return us < them
|
| 87 |
+
|
| 88 |
+
def __hash__(self):
|
| 89 |
+
return hash((self.year, self.minor, self.micro, self.releaselevel))
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/filesystems/__init__.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import importlib
|
| 2 |
+
import shutil
|
| 3 |
+
import warnings
|
| 4 |
+
from typing import List
|
| 5 |
+
|
| 6 |
+
import fsspec
|
| 7 |
+
import fsspec.asyn
|
| 8 |
+
from fsspec.implementations.local import LocalFileSystem
|
| 9 |
+
|
| 10 |
+
from . import compression
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
COMPRESSION_FILESYSTEMS: list[compression.BaseCompressedFileFileSystem] = [
|
| 14 |
+
compression.Bz2FileSystem,
|
| 15 |
+
compression.GzipFileSystem,
|
| 16 |
+
compression.Lz4FileSystem,
|
| 17 |
+
compression.XzFileSystem,
|
| 18 |
+
compression.ZstdFileSystem,
|
| 19 |
+
]
|
| 20 |
+
|
| 21 |
+
# Register custom filesystems
|
| 22 |
+
for fs_class in COMPRESSION_FILESYSTEMS:
|
| 23 |
+
if fs_class.protocol in fsspec.registry and fsspec.registry[fs_class.protocol] is not fs_class:
|
| 24 |
+
warnings.warn(f"A filesystem protocol was already set for {fs_class.protocol} and will be overwritten.")
|
| 25 |
+
fsspec.register_implementation(fs_class.protocol, fs_class, clobber=True)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def is_remote_filesystem(fs: fsspec.AbstractFileSystem) -> bool:
|
| 29 |
+
"""
|
| 30 |
+
Checks if `fs` is a remote filesystem.
|
| 31 |
+
|
| 32 |
+
Args:
|
| 33 |
+
fs (`fsspec.spec.AbstractFileSystem`):
|
| 34 |
+
An abstract super-class for pythonic file-systems, e.g. `fsspec.filesystem(\'file\')` or `s3fs.S3FileSystem`.
|
| 35 |
+
"""
|
| 36 |
+
return not isinstance(fs, LocalFileSystem)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def rename(fs: fsspec.AbstractFileSystem, src: str, dst: str):
|
| 40 |
+
"""
|
| 41 |
+
Renames the file `src` in `fs` to `dst`.
|
| 42 |
+
"""
|
| 43 |
+
if not is_remote_filesystem(fs):
|
| 44 |
+
# LocalFileSystem.mv does copy + rm, it is more efficient to simply move a local directory
|
| 45 |
+
shutil.move(fs._strip_protocol(src), fs._strip_protocol(dst))
|
| 46 |
+
else:
|
| 47 |
+
fs.mv(src, dst, recursive=True)
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/__init__.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 The HuggingFace Datasets Authors and the TensorFlow Datasets Authors.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
from typing import Dict, List, Optional, Type
|
| 16 |
+
|
| 17 |
+
from .. import config
|
| 18 |
+
from ..utils import logging
|
| 19 |
+
from .formatting import (
|
| 20 |
+
ArrowFormatter,
|
| 21 |
+
CustomFormatter,
|
| 22 |
+
Formatter,
|
| 23 |
+
PandasFormatter,
|
| 24 |
+
PythonFormatter,
|
| 25 |
+
TableFormatter,
|
| 26 |
+
TensorFormatter,
|
| 27 |
+
format_table,
|
| 28 |
+
query_table,
|
| 29 |
+
)
|
| 30 |
+
from .np_formatter import NumpyFormatter
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
logger = logging.get_logger(__name__)
|
| 34 |
+
|
| 35 |
+
_FORMAT_TYPES: dict[Optional[str], type[Formatter]] = {}
|
| 36 |
+
_FORMAT_TYPES_ALIASES: dict[Optional[str], str] = {}
|
| 37 |
+
_FORMAT_TYPES_ALIASES_UNAVAILABLE: dict[Optional[str], Exception] = {}
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def _register_formatter(
|
| 41 |
+
formatter_cls: type,
|
| 42 |
+
format_type: Optional[str],
|
| 43 |
+
aliases: Optional[list[str]] = None,
|
| 44 |
+
):
|
| 45 |
+
"""
|
| 46 |
+
Register a Formatter object using a name and optional aliases.
|
| 47 |
+
This function must be used on a Formatter class.
|
| 48 |
+
"""
|
| 49 |
+
aliases = aliases if aliases is not None else []
|
| 50 |
+
if format_type in _FORMAT_TYPES:
|
| 51 |
+
logger.warning(
|
| 52 |
+
f"Overwriting format type '{format_type}' ({_FORMAT_TYPES[format_type].__name__} -> {formatter_cls.__name__})"
|
| 53 |
+
)
|
| 54 |
+
_FORMAT_TYPES[format_type] = formatter_cls
|
| 55 |
+
for alias in set(aliases + [format_type]):
|
| 56 |
+
if alias in _FORMAT_TYPES_ALIASES:
|
| 57 |
+
logger.warning(
|
| 58 |
+
f"Overwriting format type alias '{alias}' ({_FORMAT_TYPES_ALIASES[alias]} -> {format_type})"
|
| 59 |
+
)
|
| 60 |
+
_FORMAT_TYPES_ALIASES[alias] = format_type
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def _register_unavailable_formatter(
|
| 64 |
+
unavailable_error: Exception, format_type: Optional[str], aliases: Optional[list[str]] = None
|
| 65 |
+
):
|
| 66 |
+
"""
|
| 67 |
+
Register an unavailable Formatter object using a name and optional aliases.
|
| 68 |
+
This function must be used on an Exception object that is raised when trying to get the unavailable formatter.
|
| 69 |
+
"""
|
| 70 |
+
aliases = aliases if aliases is not None else []
|
| 71 |
+
for alias in set(aliases + [format_type]):
|
| 72 |
+
_FORMAT_TYPES_ALIASES_UNAVAILABLE[alias] = unavailable_error
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
# Here we define all the available formatting functions that can be used by `Dataset.set_format`
|
| 76 |
+
_register_formatter(PythonFormatter, None, aliases=["python"])
|
| 77 |
+
_register_formatter(ArrowFormatter, "arrow", aliases=["pa", "pyarrow"])
|
| 78 |
+
_register_formatter(NumpyFormatter, "numpy", aliases=["np"])
|
| 79 |
+
_register_formatter(PandasFormatter, "pandas", aliases=["pd"])
|
| 80 |
+
_register_formatter(CustomFormatter, "custom")
|
| 81 |
+
|
| 82 |
+
if config.POLARS_AVAILABLE:
|
| 83 |
+
from .polars_formatter import PolarsFormatter
|
| 84 |
+
|
| 85 |
+
_register_formatter(PolarsFormatter, "polars", aliases=["pl"])
|
| 86 |
+
else:
|
| 87 |
+
_polars_error = ValueError("Polars needs to be installed to be able to return Polars dataframes.")
|
| 88 |
+
_register_unavailable_formatter(_polars_error, "polars", aliases=["pl"])
|
| 89 |
+
|
| 90 |
+
if config.TORCH_AVAILABLE:
|
| 91 |
+
from .torch_formatter import TorchFormatter
|
| 92 |
+
|
| 93 |
+
_register_formatter(TorchFormatter, "torch", aliases=["pt", "pytorch"])
|
| 94 |
+
else:
|
| 95 |
+
_torch_error = ValueError("PyTorch needs to be installed to be able to return PyTorch tensors.")
|
| 96 |
+
_register_unavailable_formatter(_torch_error, "torch", aliases=["pt", "pytorch"])
|
| 97 |
+
|
| 98 |
+
if config.TF_AVAILABLE:
|
| 99 |
+
from .tf_formatter import TFFormatter
|
| 100 |
+
|
| 101 |
+
_register_formatter(TFFormatter, "tensorflow", aliases=["tf"])
|
| 102 |
+
else:
|
| 103 |
+
_tf_error = ValueError("Tensorflow needs to be installed to be able to return Tensorflow tensors.")
|
| 104 |
+
_register_unavailable_formatter(_tf_error, "tensorflow", aliases=["tf"])
|
| 105 |
+
|
| 106 |
+
if config.JAX_AVAILABLE:
|
| 107 |
+
from .jax_formatter import JaxFormatter
|
| 108 |
+
|
| 109 |
+
_register_formatter(JaxFormatter, "jax", aliases=[])
|
| 110 |
+
else:
|
| 111 |
+
_jax_error = ValueError("JAX needs to be installed to be able to return JAX arrays.")
|
| 112 |
+
_register_unavailable_formatter(_jax_error, "jax", aliases=[])
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def get_format_type_from_alias(format_type: Optional[str]) -> Optional[str]:
|
| 116 |
+
"""If the given format type is a known alias, then return its main type name. Otherwise return the type with no change."""
|
| 117 |
+
if format_type in _FORMAT_TYPES_ALIASES:
|
| 118 |
+
return _FORMAT_TYPES_ALIASES[format_type]
|
| 119 |
+
else:
|
| 120 |
+
return format_type
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def get_formatter(format_type: Optional[str], **format_kwargs) -> Formatter:
|
| 124 |
+
"""
|
| 125 |
+
Factory function to get a Formatter given its type name and keyword arguments.
|
| 126 |
+
A formatter is an object that extracts and formats data from pyarrow table.
|
| 127 |
+
It defines the formatting for rows, columns and batches.
|
| 128 |
+
If the formatter for a given type name doesn't exist or is not available, an error is raised.
|
| 129 |
+
"""
|
| 130 |
+
format_type = get_format_type_from_alias(format_type)
|
| 131 |
+
if format_type in _FORMAT_TYPES:
|
| 132 |
+
return _FORMAT_TYPES[format_type](**format_kwargs)
|
| 133 |
+
if format_type in _FORMAT_TYPES_ALIASES_UNAVAILABLE:
|
| 134 |
+
raise _FORMAT_TYPES_ALIASES_UNAVAILABLE[format_type]
|
| 135 |
+
else:
|
| 136 |
+
raise ValueError(f"Format type should be one of {list(_FORMAT_TYPES.keys())}, but got '{format_type}'")
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/formatting.py
ADDED
|
@@ -0,0 +1,678 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 The HuggingFace Authors.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
import numbers
|
| 16 |
+
import operator
|
| 17 |
+
from collections.abc import Iterable, Mapping, MutableMapping
|
| 18 |
+
from functools import partial
|
| 19 |
+
|
| 20 |
+
# Lint as: python3
|
| 21 |
+
from typing import Any, Callable, Generic, Optional, TypeVar, Union
|
| 22 |
+
|
| 23 |
+
import numpy as np
|
| 24 |
+
import pandas as pd
|
| 25 |
+
import pyarrow as pa
|
| 26 |
+
|
| 27 |
+
from ..features import Features
|
| 28 |
+
from ..features.features import _ArrayXDExtensionType, _is_zero_copy_only, decode_nested_example, pandas_types_mapper
|
| 29 |
+
from ..table import Table
|
| 30 |
+
from ..utils.py_utils import no_op_if_value_is_null
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
T = TypeVar("T")
|
| 34 |
+
|
| 35 |
+
RowFormat = TypeVar("RowFormat")
|
| 36 |
+
ColumnFormat = TypeVar("ColumnFormat")
|
| 37 |
+
BatchFormat = TypeVar("BatchFormat")
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def _is_range_contiguous(key: range) -> bool:
|
| 41 |
+
return key.step == 1 and key.stop >= key.start
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def _raise_bad_key_type(key: Any):
|
| 45 |
+
raise TypeError(
|
| 46 |
+
f"Wrong key type: '{key}' of type '{type(key)}'. Expected one of int, slice, range, str or Iterable."
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def _query_table_with_indices_mapping(
|
| 51 |
+
table: Table, key: Union[int, slice, range, str, Iterable], indices: Table
|
| 52 |
+
) -> pa.Table:
|
| 53 |
+
"""
|
| 54 |
+
Query a pyarrow Table to extract the subtable that correspond to the given key.
|
| 55 |
+
The :obj:`indices` parameter corresponds to the indices mapping in case we cant to take into
|
| 56 |
+
account a shuffling or an indices selection for example.
|
| 57 |
+
The indices table must contain one column named "indices" of type uint64.
|
| 58 |
+
"""
|
| 59 |
+
if isinstance(key, int):
|
| 60 |
+
key = indices.fast_slice(key % indices.num_rows, 1).column(0)[0].as_py()
|
| 61 |
+
return _query_table(table, key)
|
| 62 |
+
if isinstance(key, slice):
|
| 63 |
+
key = range(*key.indices(indices.num_rows))
|
| 64 |
+
if isinstance(key, range):
|
| 65 |
+
if _is_range_contiguous(key) and key.start >= 0:
|
| 66 |
+
return _query_table(
|
| 67 |
+
table, [i.as_py() for i in indices.fast_slice(key.start, key.stop - key.start).column(0)]
|
| 68 |
+
)
|
| 69 |
+
else:
|
| 70 |
+
pass # treat as an iterable
|
| 71 |
+
if isinstance(key, str):
|
| 72 |
+
table = table.select([key])
|
| 73 |
+
return _query_table(table, indices.column(0).to_pylist())
|
| 74 |
+
if isinstance(key, Iterable):
|
| 75 |
+
return _query_table(table, [indices.fast_slice(i, 1).column(0)[0].as_py() for i in key])
|
| 76 |
+
|
| 77 |
+
_raise_bad_key_type(key)
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def _query_table(table: Table, key: Union[int, slice, range, str, Iterable]) -> pa.Table:
|
| 81 |
+
"""
|
| 82 |
+
Query a pyarrow Table to extract the subtable that correspond to the given key.
|
| 83 |
+
"""
|
| 84 |
+
if isinstance(key, int):
|
| 85 |
+
return table.fast_slice(key % table.num_rows, 1)
|
| 86 |
+
if isinstance(key, slice):
|
| 87 |
+
key = range(*key.indices(table.num_rows))
|
| 88 |
+
if isinstance(key, range):
|
| 89 |
+
if _is_range_contiguous(key) and key.start >= 0:
|
| 90 |
+
return table.fast_slice(key.start, key.stop - key.start)
|
| 91 |
+
else:
|
| 92 |
+
pass # treat as an iterable
|
| 93 |
+
if isinstance(key, str):
|
| 94 |
+
return table.table.drop([column for column in table.column_names if column != key])
|
| 95 |
+
if isinstance(key, Iterable):
|
| 96 |
+
key = np.fromiter(key, np.int64)
|
| 97 |
+
if len(key) == 0:
|
| 98 |
+
return table.table.slice(0, 0)
|
| 99 |
+
# don't use pyarrow.Table.take even for pyarrow >=1.0 (see https://issues.apache.org/jira/browse/ARROW-9773)
|
| 100 |
+
return table.fast_gather(key % table.num_rows)
|
| 101 |
+
|
| 102 |
+
_raise_bad_key_type(key)
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
def _is_array_with_nulls(pa_array: pa.Array) -> bool:
|
| 106 |
+
return pa_array.null_count > 0
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
class BaseArrowExtractor(Generic[RowFormat, ColumnFormat, BatchFormat]):
|
| 110 |
+
"""
|
| 111 |
+
Arrow extractor are used to extract data from pyarrow tables.
|
| 112 |
+
It makes it possible to extract rows, columns and batches.
|
| 113 |
+
These three extractions types have to be implemented.
|
| 114 |
+
"""
|
| 115 |
+
|
| 116 |
+
def extract_row(self, pa_table: pa.Table) -> RowFormat:
|
| 117 |
+
raise NotImplementedError
|
| 118 |
+
|
| 119 |
+
def extract_column(self, pa_table: pa.Table) -> ColumnFormat:
|
| 120 |
+
raise NotImplementedError
|
| 121 |
+
|
| 122 |
+
def extract_batch(self, pa_table: pa.Table) -> BatchFormat:
|
| 123 |
+
raise NotImplementedError
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
def _unnest(py_dict: dict[str, list[T]]) -> dict[str, T]:
|
| 127 |
+
"""Return the first element of a batch (dict) as a row (dict)"""
|
| 128 |
+
return {key: array[0] for key, array in py_dict.items()}
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
class SimpleArrowExtractor(BaseArrowExtractor[pa.Table, pa.Array, pa.Table]):
|
| 132 |
+
def extract_row(self, pa_table: pa.Table) -> pa.Table:
|
| 133 |
+
return pa_table
|
| 134 |
+
|
| 135 |
+
def extract_column(self, pa_table: pa.Table) -> pa.Array:
|
| 136 |
+
return pa_table.column(0)
|
| 137 |
+
|
| 138 |
+
def extract_batch(self, pa_table: pa.Table) -> pa.Table:
|
| 139 |
+
return pa_table
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
class PythonArrowExtractor(BaseArrowExtractor[dict, list, dict]):
|
| 143 |
+
def extract_row(self, pa_table: pa.Table) -> dict:
|
| 144 |
+
return _unnest(pa_table.to_pydict())
|
| 145 |
+
|
| 146 |
+
def extract_column(self, pa_table: pa.Table) -> list:
|
| 147 |
+
return pa_table.column(0).to_pylist()
|
| 148 |
+
|
| 149 |
+
def extract_batch(self, pa_table: pa.Table) -> dict:
|
| 150 |
+
return pa_table.to_pydict()
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
class NumpyArrowExtractor(BaseArrowExtractor[dict, np.ndarray, dict]):
|
| 154 |
+
def __init__(self, **np_array_kwargs):
|
| 155 |
+
self.np_array_kwargs = np_array_kwargs
|
| 156 |
+
|
| 157 |
+
def extract_row(self, pa_table: pa.Table) -> dict:
|
| 158 |
+
return _unnest(self.extract_batch(pa_table))
|
| 159 |
+
|
| 160 |
+
def extract_column(self, pa_table: pa.Table) -> np.ndarray:
|
| 161 |
+
return self._arrow_array_to_numpy(pa_table[pa_table.column_names[0]])
|
| 162 |
+
|
| 163 |
+
def extract_batch(self, pa_table: pa.Table) -> dict:
|
| 164 |
+
return {col: self._arrow_array_to_numpy(pa_table[col]) for col in pa_table.column_names}
|
| 165 |
+
|
| 166 |
+
def _arrow_array_to_numpy(self, pa_array: pa.Array) -> np.ndarray:
|
| 167 |
+
if isinstance(pa_array, pa.ChunkedArray):
|
| 168 |
+
if isinstance(pa_array.type, _ArrayXDExtensionType):
|
| 169 |
+
# don't call to_pylist() to preserve dtype of the fixed-size array
|
| 170 |
+
zero_copy_only = _is_zero_copy_only(pa_array.type.storage_dtype, unnest=True)
|
| 171 |
+
array: list = [
|
| 172 |
+
row for chunk in pa_array.chunks for row in chunk.to_numpy(zero_copy_only=zero_copy_only)
|
| 173 |
+
]
|
| 174 |
+
else:
|
| 175 |
+
zero_copy_only = _is_zero_copy_only(pa_array.type) and all(
|
| 176 |
+
not _is_array_with_nulls(chunk) for chunk in pa_array.chunks
|
| 177 |
+
)
|
| 178 |
+
array: list = [
|
| 179 |
+
row for chunk in pa_array.chunks for row in chunk.to_numpy(zero_copy_only=zero_copy_only)
|
| 180 |
+
]
|
| 181 |
+
else:
|
| 182 |
+
if isinstance(pa_array.type, _ArrayXDExtensionType):
|
| 183 |
+
# don't call to_pylist() to preserve dtype of the fixed-size array
|
| 184 |
+
zero_copy_only = _is_zero_copy_only(pa_array.type.storage_dtype, unnest=True)
|
| 185 |
+
array: list = pa_array.to_numpy(zero_copy_only=zero_copy_only)
|
| 186 |
+
else:
|
| 187 |
+
zero_copy_only = _is_zero_copy_only(pa_array.type) and not _is_array_with_nulls(pa_array)
|
| 188 |
+
array: list = pa_array.to_numpy(zero_copy_only=zero_copy_only).tolist()
|
| 189 |
+
|
| 190 |
+
if len(array) > 0:
|
| 191 |
+
if any(
|
| 192 |
+
(isinstance(x, np.ndarray) and (x.dtype == object or x.shape != array[0].shape))
|
| 193 |
+
or (isinstance(x, float) and np.isnan(x))
|
| 194 |
+
for x in array
|
| 195 |
+
):
|
| 196 |
+
if np.lib.NumpyVersion(np.__version__) >= "2.0.0b1":
|
| 197 |
+
return np.asarray(array, dtype=object)
|
| 198 |
+
return np.array(array, copy=False, dtype=object)
|
| 199 |
+
if np.lib.NumpyVersion(np.__version__) >= "2.0.0b1":
|
| 200 |
+
return np.asarray(array)
|
| 201 |
+
else:
|
| 202 |
+
return np.array(array, copy=False)
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
class PandasArrowExtractor(BaseArrowExtractor[pd.DataFrame, pd.Series, pd.DataFrame]):
|
| 206 |
+
def extract_row(self, pa_table: pa.Table) -> pd.DataFrame:
|
| 207 |
+
return pa_table.slice(length=1).to_pandas(types_mapper=pandas_types_mapper)
|
| 208 |
+
|
| 209 |
+
def extract_column(self, pa_table: pa.Table) -> pd.Series:
|
| 210 |
+
return pa_table.select([0]).to_pandas(types_mapper=pandas_types_mapper)[pa_table.column_names[0]]
|
| 211 |
+
|
| 212 |
+
def extract_batch(self, pa_table: pa.Table) -> pd.DataFrame:
|
| 213 |
+
return pa_table.to_pandas(types_mapper=pandas_types_mapper)
|
| 214 |
+
|
| 215 |
+
|
| 216 |
+
class PythonFeaturesDecoder:
|
| 217 |
+
def __init__(
|
| 218 |
+
self, features: Optional[Features], token_per_repo_id: Optional[dict[str, Union[str, bool, None]]] = None
|
| 219 |
+
):
|
| 220 |
+
self.features = features
|
| 221 |
+
self.token_per_repo_id = token_per_repo_id
|
| 222 |
+
|
| 223 |
+
def decode_row(self, row: dict) -> dict:
|
| 224 |
+
return self.features.decode_example(row, token_per_repo_id=self.token_per_repo_id) if self.features else row
|
| 225 |
+
|
| 226 |
+
def decode_column(self, column: list, column_name: str) -> list:
|
| 227 |
+
return (
|
| 228 |
+
self.features.decode_column(column, column_name, token_per_repo_id=self.token_per_repo_id)
|
| 229 |
+
if self.features
|
| 230 |
+
else column
|
| 231 |
+
)
|
| 232 |
+
|
| 233 |
+
def decode_batch(self, batch: dict) -> dict:
|
| 234 |
+
return self.features.decode_batch(batch, token_per_repo_id=self.token_per_repo_id) if self.features else batch
|
| 235 |
+
|
| 236 |
+
|
| 237 |
+
class PandasFeaturesDecoder:
|
| 238 |
+
def __init__(self, features: Optional[Features]):
|
| 239 |
+
self.features = features
|
| 240 |
+
|
| 241 |
+
def decode_row(self, row: pd.DataFrame) -> pd.DataFrame:
|
| 242 |
+
decode = (
|
| 243 |
+
{
|
| 244 |
+
column_name: no_op_if_value_is_null(partial(decode_nested_example, feature))
|
| 245 |
+
for column_name, feature in self.features.items()
|
| 246 |
+
if self.features._column_requires_decoding[column_name]
|
| 247 |
+
}
|
| 248 |
+
if self.features
|
| 249 |
+
else {}
|
| 250 |
+
)
|
| 251 |
+
if decode:
|
| 252 |
+
row[list(decode.keys())] = row.transform(decode)
|
| 253 |
+
return row
|
| 254 |
+
|
| 255 |
+
def decode_column(self, column: pd.Series, column_name: str) -> pd.Series:
|
| 256 |
+
decode = (
|
| 257 |
+
no_op_if_value_is_null(partial(decode_nested_example, self.features[column_name]))
|
| 258 |
+
if self.features and column_name in self.features and self.features._column_requires_decoding[column_name]
|
| 259 |
+
else None
|
| 260 |
+
)
|
| 261 |
+
if decode:
|
| 262 |
+
column = column.transform(decode)
|
| 263 |
+
return column
|
| 264 |
+
|
| 265 |
+
def decode_batch(self, batch: pd.DataFrame) -> pd.DataFrame:
|
| 266 |
+
return self.decode_row(batch)
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
class LazyDict(MutableMapping):
|
| 270 |
+
"""A dictionary backed by Arrow data. The values are formatted on-the-fly when accessing the dictionary."""
|
| 271 |
+
|
| 272 |
+
def __init__(self, pa_table: pa.Table, formatter: "Formatter"):
|
| 273 |
+
self.pa_table = pa_table
|
| 274 |
+
self.formatter = formatter
|
| 275 |
+
|
| 276 |
+
self.data = dict.fromkeys(pa_table.column_names)
|
| 277 |
+
self.keys_to_format = set(self.data.keys())
|
| 278 |
+
|
| 279 |
+
def __len__(self):
|
| 280 |
+
return len(self.data)
|
| 281 |
+
|
| 282 |
+
def __getitem__(self, key):
|
| 283 |
+
value = self.data[key]
|
| 284 |
+
if key in self.keys_to_format:
|
| 285 |
+
value = self.format(key)
|
| 286 |
+
self.data[key] = value
|
| 287 |
+
self.keys_to_format.remove(key)
|
| 288 |
+
return value
|
| 289 |
+
|
| 290 |
+
def __setitem__(self, key, value):
|
| 291 |
+
if key in self.keys_to_format:
|
| 292 |
+
self.keys_to_format.remove(key)
|
| 293 |
+
self.data[key] = value
|
| 294 |
+
|
| 295 |
+
def __delitem__(self, key) -> None:
|
| 296 |
+
if key in self.keys_to_format:
|
| 297 |
+
self.keys_to_format.remove(key)
|
| 298 |
+
del self.data[key]
|
| 299 |
+
|
| 300 |
+
def __iter__(self):
|
| 301 |
+
return iter(self.data)
|
| 302 |
+
|
| 303 |
+
def __contains__(self, key):
|
| 304 |
+
return key in self.data
|
| 305 |
+
|
| 306 |
+
def __repr__(self):
|
| 307 |
+
self._format_all()
|
| 308 |
+
return repr(self.data)
|
| 309 |
+
|
| 310 |
+
def __or__(self, other):
|
| 311 |
+
if isinstance(other, LazyDict):
|
| 312 |
+
inst = self.copy()
|
| 313 |
+
other = other.copy()
|
| 314 |
+
other._format_all()
|
| 315 |
+
inst.keys_to_format -= other.data.keys()
|
| 316 |
+
inst.data = inst.data | other.data
|
| 317 |
+
return inst
|
| 318 |
+
if isinstance(other, dict):
|
| 319 |
+
inst = self.copy()
|
| 320 |
+
inst.keys_to_format -= other.keys()
|
| 321 |
+
inst.data = inst.data | other
|
| 322 |
+
return inst
|
| 323 |
+
return NotImplemented
|
| 324 |
+
|
| 325 |
+
def __ror__(self, other):
|
| 326 |
+
if isinstance(other, LazyDict):
|
| 327 |
+
inst = self.copy()
|
| 328 |
+
other = other.copy()
|
| 329 |
+
other._format_all()
|
| 330 |
+
inst.keys_to_format -= other.data.keys()
|
| 331 |
+
inst.data = other.data | inst.data
|
| 332 |
+
return inst
|
| 333 |
+
if isinstance(other, dict):
|
| 334 |
+
inst = self.copy()
|
| 335 |
+
inst.keys_to_format -= other.keys()
|
| 336 |
+
inst.data = other | inst.data
|
| 337 |
+
return inst
|
| 338 |
+
return NotImplemented
|
| 339 |
+
|
| 340 |
+
def __ior__(self, other):
|
| 341 |
+
if isinstance(other, LazyDict):
|
| 342 |
+
other = other.copy()
|
| 343 |
+
other._format_all()
|
| 344 |
+
self.keys_to_format -= other.data.keys()
|
| 345 |
+
self.data |= other.data
|
| 346 |
+
else:
|
| 347 |
+
self.keys_to_format -= other.keys()
|
| 348 |
+
self.data |= other
|
| 349 |
+
return self
|
| 350 |
+
|
| 351 |
+
def __copy__(self):
|
| 352 |
+
# Identical to `UserDict.__copy__`
|
| 353 |
+
inst = self.__class__.__new__(self.__class__)
|
| 354 |
+
inst.__dict__.update(self.__dict__)
|
| 355 |
+
# Create a copy and avoid triggering descriptors
|
| 356 |
+
inst.__dict__["data"] = self.__dict__["data"].copy()
|
| 357 |
+
inst.__dict__["keys_to_format"] = self.__dict__["keys_to_format"].copy()
|
| 358 |
+
return inst
|
| 359 |
+
|
| 360 |
+
def copy(self):
|
| 361 |
+
import copy
|
| 362 |
+
|
| 363 |
+
return copy.copy(self)
|
| 364 |
+
|
| 365 |
+
@classmethod
|
| 366 |
+
def fromkeys(cls, iterable, value=None):
|
| 367 |
+
raise NotImplementedError
|
| 368 |
+
|
| 369 |
+
def format(self, key):
|
| 370 |
+
raise NotImplementedError
|
| 371 |
+
|
| 372 |
+
def _format_all(self):
|
| 373 |
+
for key in self.keys_to_format:
|
| 374 |
+
self.data[key] = self.format(key)
|
| 375 |
+
self.keys_to_format.clear()
|
| 376 |
+
|
| 377 |
+
|
| 378 |
+
class LazyRow(LazyDict):
|
| 379 |
+
def format(self, key):
|
| 380 |
+
return self.formatter.format_column(self.pa_table.select([key]))[0]
|
| 381 |
+
|
| 382 |
+
|
| 383 |
+
class LazyBatch(LazyDict):
|
| 384 |
+
def format(self, key):
|
| 385 |
+
return self.formatter.format_column(self.pa_table.select([key]))
|
| 386 |
+
|
| 387 |
+
|
| 388 |
+
class Formatter(Generic[RowFormat, ColumnFormat, BatchFormat]):
|
| 389 |
+
"""
|
| 390 |
+
A formatter is an object that extracts and formats data from pyarrow tables.
|
| 391 |
+
It defines the formatting for rows, columns and batches.
|
| 392 |
+
"""
|
| 393 |
+
|
| 394 |
+
simple_arrow_extractor = SimpleArrowExtractor
|
| 395 |
+
python_arrow_extractor = PythonArrowExtractor
|
| 396 |
+
numpy_arrow_extractor = NumpyArrowExtractor
|
| 397 |
+
pandas_arrow_extractor = PandasArrowExtractor
|
| 398 |
+
|
| 399 |
+
def __init__(
|
| 400 |
+
self,
|
| 401 |
+
features: Optional[Features] = None,
|
| 402 |
+
token_per_repo_id: Optional[dict[str, Union[str, bool, None]]] = None,
|
| 403 |
+
):
|
| 404 |
+
self.features = features
|
| 405 |
+
self.token_per_repo_id = token_per_repo_id
|
| 406 |
+
self.python_features_decoder = PythonFeaturesDecoder(self.features, self.token_per_repo_id)
|
| 407 |
+
self.pandas_features_decoder = PandasFeaturesDecoder(self.features)
|
| 408 |
+
|
| 409 |
+
def __call__(self, pa_table: pa.Table, query_type: str) -> Union[RowFormat, ColumnFormat, BatchFormat]:
|
| 410 |
+
if query_type == "row":
|
| 411 |
+
return self.format_row(pa_table)
|
| 412 |
+
elif query_type == "column":
|
| 413 |
+
return self.format_column(pa_table)
|
| 414 |
+
elif query_type == "batch":
|
| 415 |
+
return self.format_batch(pa_table)
|
| 416 |
+
|
| 417 |
+
def format_row(self, pa_table: pa.Table) -> RowFormat:
|
| 418 |
+
raise NotImplementedError
|
| 419 |
+
|
| 420 |
+
def format_column(self, pa_table: pa.Table) -> ColumnFormat:
|
| 421 |
+
raise NotImplementedError
|
| 422 |
+
|
| 423 |
+
def format_batch(self, pa_table: pa.Table) -> BatchFormat:
|
| 424 |
+
raise NotImplementedError
|
| 425 |
+
|
| 426 |
+
|
| 427 |
+
class TensorFormatter(Formatter[RowFormat, ColumnFormat, BatchFormat]):
|
| 428 |
+
def recursive_tensorize(self, data_struct: dict):
|
| 429 |
+
raise NotImplementedError
|
| 430 |
+
|
| 431 |
+
|
| 432 |
+
class TableFormatter(Formatter[RowFormat, ColumnFormat, BatchFormat]):
|
| 433 |
+
table_type: str
|
| 434 |
+
column_type: str
|
| 435 |
+
|
| 436 |
+
|
| 437 |
+
class ArrowFormatter(TableFormatter[pa.Table, pa.Array, pa.Table]):
|
| 438 |
+
table_type = "arrow table"
|
| 439 |
+
column_type = "arrow array"
|
| 440 |
+
|
| 441 |
+
def format_row(self, pa_table: pa.Table) -> pa.Table:
|
| 442 |
+
return self.simple_arrow_extractor().extract_row(pa_table)
|
| 443 |
+
|
| 444 |
+
def format_column(self, pa_table: pa.Table) -> pa.Array:
|
| 445 |
+
return self.simple_arrow_extractor().extract_column(pa_table)
|
| 446 |
+
|
| 447 |
+
def format_batch(self, pa_table: pa.Table) -> pa.Table:
|
| 448 |
+
return self.simple_arrow_extractor().extract_batch(pa_table)
|
| 449 |
+
|
| 450 |
+
|
| 451 |
+
class PythonFormatter(Formatter[Mapping, list, Mapping]):
|
| 452 |
+
def __init__(self, features=None, lazy=False, token_per_repo_id=None):
|
| 453 |
+
super().__init__(features, token_per_repo_id)
|
| 454 |
+
self.lazy = lazy
|
| 455 |
+
|
| 456 |
+
def format_row(self, pa_table: pa.Table) -> Mapping:
|
| 457 |
+
if self.lazy:
|
| 458 |
+
return LazyRow(pa_table, self)
|
| 459 |
+
row = self.python_arrow_extractor().extract_row(pa_table)
|
| 460 |
+
row = self.python_features_decoder.decode_row(row)
|
| 461 |
+
return row
|
| 462 |
+
|
| 463 |
+
def format_column(self, pa_table: pa.Table) -> list:
|
| 464 |
+
column = self.python_arrow_extractor().extract_column(pa_table)
|
| 465 |
+
column = self.python_features_decoder.decode_column(column, pa_table.column_names[0])
|
| 466 |
+
return column
|
| 467 |
+
|
| 468 |
+
def format_batch(self, pa_table: pa.Table) -> Mapping:
|
| 469 |
+
if self.lazy:
|
| 470 |
+
return LazyBatch(pa_table, self)
|
| 471 |
+
batch = self.python_arrow_extractor().extract_batch(pa_table)
|
| 472 |
+
batch = self.python_features_decoder.decode_batch(batch)
|
| 473 |
+
return batch
|
| 474 |
+
|
| 475 |
+
|
| 476 |
+
class PandasFormatter(TableFormatter[pd.DataFrame, pd.Series, pd.DataFrame]):
|
| 477 |
+
table_type = "pandas dataframe"
|
| 478 |
+
column_type = "pandas series"
|
| 479 |
+
|
| 480 |
+
def format_row(self, pa_table: pa.Table) -> pd.DataFrame:
|
| 481 |
+
row = self.pandas_arrow_extractor().extract_row(pa_table)
|
| 482 |
+
row = self.pandas_features_decoder.decode_row(row)
|
| 483 |
+
return row
|
| 484 |
+
|
| 485 |
+
def format_column(self, pa_table: pa.Table) -> pd.Series:
|
| 486 |
+
column = self.pandas_arrow_extractor().extract_column(pa_table)
|
| 487 |
+
column = self.pandas_features_decoder.decode_column(column, pa_table.column_names[0])
|
| 488 |
+
return column
|
| 489 |
+
|
| 490 |
+
def format_batch(self, pa_table: pa.Table) -> pd.DataFrame:
|
| 491 |
+
row = self.pandas_arrow_extractor().extract_batch(pa_table)
|
| 492 |
+
row = self.pandas_features_decoder.decode_batch(row)
|
| 493 |
+
return row
|
| 494 |
+
|
| 495 |
+
|
| 496 |
+
class CustomFormatter(Formatter[dict, ColumnFormat, dict]):
|
| 497 |
+
"""
|
| 498 |
+
A user-defined custom formatter function defined by a ``transform``.
|
| 499 |
+
The transform must take as input a batch of data extracted for an arrow table using the python extractor,
|
| 500 |
+
and return a batch.
|
| 501 |
+
If the output batch is not a dict, then output_all_columns won't work.
|
| 502 |
+
If the output batch has several fields, then querying a single column won't work since we don't know which field
|
| 503 |
+
to return.
|
| 504 |
+
"""
|
| 505 |
+
|
| 506 |
+
def __init__(self, transform: Callable[[dict], dict], features=None, token_per_repo_id=None, **kwargs):
|
| 507 |
+
super().__init__(features=features, token_per_repo_id=token_per_repo_id)
|
| 508 |
+
self.transform = transform
|
| 509 |
+
|
| 510 |
+
def format_row(self, pa_table: pa.Table) -> dict:
|
| 511 |
+
formatted_batch = self.format_batch(pa_table)
|
| 512 |
+
try:
|
| 513 |
+
return _unnest(formatted_batch)
|
| 514 |
+
except Exception as exc:
|
| 515 |
+
raise TypeError(
|
| 516 |
+
f"Custom formatting function must return a dict of sequences to be able to pick a row, but got {formatted_batch}"
|
| 517 |
+
) from exc
|
| 518 |
+
|
| 519 |
+
def format_column(self, pa_table: pa.Table) -> ColumnFormat:
|
| 520 |
+
formatted_batch = self.format_batch(pa_table)
|
| 521 |
+
if hasattr(formatted_batch, "keys"):
|
| 522 |
+
if len(formatted_batch.keys()) > 1:
|
| 523 |
+
raise TypeError(
|
| 524 |
+
"Tried to query a column but the custom formatting function returns too many columns. "
|
| 525 |
+
f"Only one column was expected but got columns {list(formatted_batch.keys())}."
|
| 526 |
+
)
|
| 527 |
+
else:
|
| 528 |
+
raise TypeError(
|
| 529 |
+
f"Custom formatting function must return a dict to be able to pick a row, but got {formatted_batch}"
|
| 530 |
+
)
|
| 531 |
+
try:
|
| 532 |
+
return formatted_batch[pa_table.column_names[0]]
|
| 533 |
+
except Exception as exc:
|
| 534 |
+
raise TypeError(
|
| 535 |
+
f"Custom formatting function must return a dict to be able to pick a row, but got {formatted_batch}"
|
| 536 |
+
) from exc
|
| 537 |
+
|
| 538 |
+
def format_batch(self, pa_table: pa.Table) -> dict:
|
| 539 |
+
batch = self.python_arrow_extractor().extract_batch(pa_table)
|
| 540 |
+
batch = self.python_features_decoder.decode_batch(batch)
|
| 541 |
+
return self.transform(batch)
|
| 542 |
+
|
| 543 |
+
|
| 544 |
+
def _check_valid_column_key(key: str, columns: list[str]) -> None:
|
| 545 |
+
if key not in columns:
|
| 546 |
+
raise KeyError(f"Column {key} not in the dataset. Current columns in the dataset: {columns}")
|
| 547 |
+
|
| 548 |
+
|
| 549 |
+
def _check_valid_index_key(key: Union[int, slice, range, Iterable], size: int) -> None:
|
| 550 |
+
if isinstance(key, int):
|
| 551 |
+
if (key < 0 and key + size < 0) or (key >= size):
|
| 552 |
+
raise IndexError(f"Invalid key: {key} is out of bounds for size {size}")
|
| 553 |
+
return
|
| 554 |
+
elif isinstance(key, slice):
|
| 555 |
+
pass
|
| 556 |
+
elif isinstance(key, range):
|
| 557 |
+
if len(key) > 0:
|
| 558 |
+
_check_valid_index_key(max(key), size=size)
|
| 559 |
+
_check_valid_index_key(min(key), size=size)
|
| 560 |
+
elif isinstance(key, Iterable):
|
| 561 |
+
if len(key) > 0:
|
| 562 |
+
_check_valid_index_key(int(max(key)), size=size)
|
| 563 |
+
_check_valid_index_key(int(min(key)), size=size)
|
| 564 |
+
else:
|
| 565 |
+
_raise_bad_key_type(key)
|
| 566 |
+
|
| 567 |
+
|
| 568 |
+
def key_to_query_type(key: Union[int, slice, range, str, Iterable]) -> str:
|
| 569 |
+
if isinstance(key, numbers.Integral):
|
| 570 |
+
return "row"
|
| 571 |
+
elif isinstance(key, str):
|
| 572 |
+
return "column"
|
| 573 |
+
elif isinstance(key, (slice, range, Iterable)):
|
| 574 |
+
return "batch"
|
| 575 |
+
_raise_bad_key_type(key)
|
| 576 |
+
|
| 577 |
+
|
| 578 |
+
def query_table(
|
| 579 |
+
table: Table,
|
| 580 |
+
key: Union[int, slice, range, str, Iterable],
|
| 581 |
+
indices: Optional[Table] = None,
|
| 582 |
+
) -> pa.Table:
|
| 583 |
+
"""
|
| 584 |
+
Query a Table to extract the subtable that correspond to the given key.
|
| 585 |
+
|
| 586 |
+
Args:
|
| 587 |
+
table (``datasets.table.Table``): The input Table to query from
|
| 588 |
+
key (``Union[int, slice, range, str, Iterable]``): The key can be of different types:
|
| 589 |
+
- an integer i: the subtable containing only the i-th row
|
| 590 |
+
- a slice [i:j:k]: the subtable containing the rows that correspond to this slice
|
| 591 |
+
- a range(i, j, k): the subtable containing the rows that correspond to this range
|
| 592 |
+
- a string c: the subtable containing all the rows but only the column c
|
| 593 |
+
- an iterable l: the subtable that is the concatenation of all the i-th rows for all i in the iterable
|
| 594 |
+
indices (Optional ``datasets.table.Table``): If not None, it is used to re-map the given key to the table rows.
|
| 595 |
+
The indices table must contain one column named "indices" of type uint64.
|
| 596 |
+
This is used in case of shuffling or rows selection.
|
| 597 |
+
|
| 598 |
+
|
| 599 |
+
Returns:
|
| 600 |
+
``pyarrow.Table``: the result of the query on the input table
|
| 601 |
+
"""
|
| 602 |
+
# Check if key is valid
|
| 603 |
+
if not isinstance(key, (int, slice, range, str, Iterable)):
|
| 604 |
+
try:
|
| 605 |
+
key = operator.index(key)
|
| 606 |
+
except TypeError:
|
| 607 |
+
_raise_bad_key_type(key)
|
| 608 |
+
if isinstance(key, str):
|
| 609 |
+
_check_valid_column_key(key, table.column_names)
|
| 610 |
+
else:
|
| 611 |
+
size = indices.num_rows if indices is not None else table.num_rows
|
| 612 |
+
_check_valid_index_key(key, size)
|
| 613 |
+
# Query the main table
|
| 614 |
+
if indices is None:
|
| 615 |
+
pa_subtable = _query_table(table, key)
|
| 616 |
+
else:
|
| 617 |
+
pa_subtable = _query_table_with_indices_mapping(table, key, indices=indices)
|
| 618 |
+
return pa_subtable
|
| 619 |
+
|
| 620 |
+
|
| 621 |
+
def format_table(
|
| 622 |
+
table: Table,
|
| 623 |
+
key: Union[int, slice, range, str, Iterable],
|
| 624 |
+
formatter: Formatter,
|
| 625 |
+
format_columns: Optional[list] = None,
|
| 626 |
+
output_all_columns=False,
|
| 627 |
+
):
|
| 628 |
+
"""
|
| 629 |
+
Format a Table depending on the key that was used and a Formatter object.
|
| 630 |
+
|
| 631 |
+
Args:
|
| 632 |
+
table (``datasets.table.Table``): The input Table to format
|
| 633 |
+
key (``Union[int, slice, range, str, Iterable]``): Depending on the key that was used, the formatter formats
|
| 634 |
+
the table as either a row, a column or a batch.
|
| 635 |
+
formatter (``datasets.formatting.formatting.Formatter``): Any subclass of a Formatter such as
|
| 636 |
+
PythonFormatter, NumpyFormatter, etc.
|
| 637 |
+
format_columns (:obj:`List[str]`, optional): if not None, it defines the columns that will be formatted using the
|
| 638 |
+
given formatter. Other columns are discarded (unless ``output_all_columns`` is True)
|
| 639 |
+
output_all_columns (:obj:`bool`, defaults to False). If True, the formatted output is completed using the columns
|
| 640 |
+
that are not in the ``format_columns`` list. For these columns, the PythonFormatter is used.
|
| 641 |
+
|
| 642 |
+
|
| 643 |
+
Returns:
|
| 644 |
+
A row, column or batch formatted object defined by the Formatter:
|
| 645 |
+
- the PythonFormatter returns a dictionary for a row or a batch, and a list for a column.
|
| 646 |
+
- the NumpyFormatter returns a dictionary for a row or a batch, and a np.array for a column.
|
| 647 |
+
- the PandasFormatter returns a pd.DataFrame for a row or a batch, and a pd.Series for a column.
|
| 648 |
+
- the TorchFormatter returns a dictionary for a row or a batch, and a torch.Tensor for a column.
|
| 649 |
+
- the TFFormatter returns a dictionary for a row or a batch, and a tf.Tensor for a column.
|
| 650 |
+
"""
|
| 651 |
+
if isinstance(table, Table):
|
| 652 |
+
pa_table = table.table
|
| 653 |
+
else:
|
| 654 |
+
pa_table = table
|
| 655 |
+
query_type = key_to_query_type(key)
|
| 656 |
+
python_formatter = PythonFormatter(features=formatter.features)
|
| 657 |
+
if format_columns is None:
|
| 658 |
+
return formatter(pa_table, query_type=query_type)
|
| 659 |
+
elif query_type == "column":
|
| 660 |
+
if key in format_columns:
|
| 661 |
+
return formatter(pa_table, query_type)
|
| 662 |
+
else:
|
| 663 |
+
return python_formatter(pa_table, query_type=query_type)
|
| 664 |
+
else:
|
| 665 |
+
pa_table_to_format = pa_table.drop(col for col in pa_table.column_names if col not in format_columns)
|
| 666 |
+
formatted_output = formatter(pa_table_to_format, query_type=query_type)
|
| 667 |
+
if output_all_columns:
|
| 668 |
+
if isinstance(formatted_output, MutableMapping):
|
| 669 |
+
pa_table_with_remaining_columns = pa_table.drop(
|
| 670 |
+
col for col in pa_table.column_names if col in format_columns
|
| 671 |
+
)
|
| 672 |
+
remaining_columns_dict = python_formatter(pa_table_with_remaining_columns, query_type=query_type)
|
| 673 |
+
formatted_output.update(remaining_columns_dict)
|
| 674 |
+
else:
|
| 675 |
+
raise TypeError(
|
| 676 |
+
f"Custom formatting function must return a dict to work with output_all_columns=True, but got {formatted_output}"
|
| 677 |
+
)
|
| 678 |
+
return formatted_output
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/jax_formatter.py
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2021 The HuggingFace Authors.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
# Lint as: python3
|
| 16 |
+
import sys
|
| 17 |
+
from collections.abc import Mapping
|
| 18 |
+
from typing import TYPE_CHECKING, Optional
|
| 19 |
+
|
| 20 |
+
import numpy as np
|
| 21 |
+
import pyarrow as pa
|
| 22 |
+
|
| 23 |
+
from .. import config
|
| 24 |
+
from ..utils.logging import get_logger
|
| 25 |
+
from ..utils.py_utils import map_nested
|
| 26 |
+
from .formatting import TensorFormatter
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
if TYPE_CHECKING:
|
| 30 |
+
import jax
|
| 31 |
+
import jaxlib
|
| 32 |
+
|
| 33 |
+
logger = get_logger()
|
| 34 |
+
|
| 35 |
+
DEVICE_MAPPING: Optional[dict] = None
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class JaxFormatter(TensorFormatter[Mapping, "jax.Array", Mapping]):
|
| 39 |
+
def __init__(self, features=None, device=None, token_per_repo_id=None, **jnp_array_kwargs):
|
| 40 |
+
super().__init__(features=features, token_per_repo_id=token_per_repo_id)
|
| 41 |
+
import jax
|
| 42 |
+
from jaxlib.xla_client import Device
|
| 43 |
+
|
| 44 |
+
if isinstance(device, Device):
|
| 45 |
+
raise ValueError(
|
| 46 |
+
f"Expected {device} to be a `str` not {type(device)}, as `jaxlib.xla_extension.Device` "
|
| 47 |
+
"is not serializable neither with `pickle` nor with `dill`. Instead you can surround "
|
| 48 |
+
"the device with `str()` to get its string identifier that will be internally mapped "
|
| 49 |
+
"to the actual `jaxlib.xla_extension.Device`."
|
| 50 |
+
)
|
| 51 |
+
self.device = device if isinstance(device, str) else str(jax.devices()[0])
|
| 52 |
+
# using global variable since `jaxlib.xla_extension.Device` is not serializable neither
|
| 53 |
+
# with `pickle` nor with `dill`, so we need to use a global variable instead
|
| 54 |
+
global DEVICE_MAPPING
|
| 55 |
+
if DEVICE_MAPPING is None:
|
| 56 |
+
DEVICE_MAPPING = self._map_devices_to_str()
|
| 57 |
+
if self.device not in list(DEVICE_MAPPING.keys()):
|
| 58 |
+
logger.warning(
|
| 59 |
+
f"Device with string identifier {self.device} not listed among the available "
|
| 60 |
+
f"devices: {list(DEVICE_MAPPING.keys())}, so falling back to the default "
|
| 61 |
+
f"device: {str(jax.devices()[0])}."
|
| 62 |
+
)
|
| 63 |
+
self.device = str(jax.devices()[0])
|
| 64 |
+
self.jnp_array_kwargs = jnp_array_kwargs
|
| 65 |
+
|
| 66 |
+
@staticmethod
|
| 67 |
+
def _map_devices_to_str() -> dict[str, "jaxlib.xla_extension.Device"]:
|
| 68 |
+
import jax
|
| 69 |
+
|
| 70 |
+
return {str(device): device for device in jax.devices()}
|
| 71 |
+
|
| 72 |
+
def _consolidate(self, column):
|
| 73 |
+
import jax
|
| 74 |
+
import jax.numpy as jnp
|
| 75 |
+
|
| 76 |
+
if isinstance(column, list) and column:
|
| 77 |
+
if all(
|
| 78 |
+
isinstance(x, jax.Array) and x.shape == column[0].shape and x.dtype == column[0].dtype for x in column
|
| 79 |
+
):
|
| 80 |
+
return jnp.stack(column, axis=0)
|
| 81 |
+
return column
|
| 82 |
+
|
| 83 |
+
def _tensorize(self, value):
|
| 84 |
+
import jax
|
| 85 |
+
import jax.numpy as jnp
|
| 86 |
+
|
| 87 |
+
if isinstance(value, (str, bytes, type(None))):
|
| 88 |
+
return value
|
| 89 |
+
elif isinstance(value, (np.character, np.ndarray)) and np.issubdtype(value.dtype, np.character):
|
| 90 |
+
return value.tolist()
|
| 91 |
+
|
| 92 |
+
default_dtype = {}
|
| 93 |
+
|
| 94 |
+
if isinstance(value, (np.number, np.ndarray)) and np.issubdtype(value.dtype, np.integer):
|
| 95 |
+
# the default int precision depends on the jax config
|
| 96 |
+
# see https://jax.readthedocs.io/en/latest/notebooks/Common_Gotchas_in_JAX.html#double-64bit-precision
|
| 97 |
+
if jax.config.jax_enable_x64:
|
| 98 |
+
default_dtype = {"dtype": jnp.int64}
|
| 99 |
+
else:
|
| 100 |
+
default_dtype = {"dtype": jnp.int32}
|
| 101 |
+
elif isinstance(value, (np.number, np.ndarray)) and np.issubdtype(value.dtype, np.floating):
|
| 102 |
+
default_dtype = {"dtype": jnp.float32}
|
| 103 |
+
|
| 104 |
+
if config.PIL_AVAILABLE and "PIL" in sys.modules:
|
| 105 |
+
import PIL.Image
|
| 106 |
+
|
| 107 |
+
if isinstance(value, PIL.Image.Image):
|
| 108 |
+
value = np.asarray(value)
|
| 109 |
+
if config.TORCHVISION_AVAILABLE and "torchvision" in sys.modules:
|
| 110 |
+
try:
|
| 111 |
+
from torchvision.io import VideoReader
|
| 112 |
+
|
| 113 |
+
if isinstance(value, VideoReader):
|
| 114 |
+
return value # TODO(QL): set output to jax arrays ?
|
| 115 |
+
except ImportError:
|
| 116 |
+
pass
|
| 117 |
+
if config.TORCHCODEC_AVAILABLE and "torchcodec" in sys.modules:
|
| 118 |
+
from torchcodec.decoders import AudioDecoder, VideoDecoder
|
| 119 |
+
|
| 120 |
+
if isinstance(value, (VideoDecoder, AudioDecoder)):
|
| 121 |
+
return value # TODO(QL): set output to jax arrays ?
|
| 122 |
+
|
| 123 |
+
# using global variable since `jaxlib.xla_extension.Device` is not serializable neither
|
| 124 |
+
# with `pickle` nor with `dill`, so we need to use a global variable instead
|
| 125 |
+
global DEVICE_MAPPING
|
| 126 |
+
if DEVICE_MAPPING is None:
|
| 127 |
+
DEVICE_MAPPING = self._map_devices_to_str()
|
| 128 |
+
|
| 129 |
+
with jax.default_device(DEVICE_MAPPING[self.device]):
|
| 130 |
+
# calling jnp.array on a np.ndarray does copy the data
|
| 131 |
+
# see https://github.com/google/jax/issues/4486
|
| 132 |
+
return jnp.array(value, **{**default_dtype, **self.jnp_array_kwargs})
|
| 133 |
+
|
| 134 |
+
def _recursive_tensorize(self, data_struct):
|
| 135 |
+
import jax
|
| 136 |
+
|
| 137 |
+
# support for torch, tf, jax etc.
|
| 138 |
+
if config.TORCH_AVAILABLE and "torch" in sys.modules:
|
| 139 |
+
import torch
|
| 140 |
+
|
| 141 |
+
if isinstance(data_struct, torch.Tensor):
|
| 142 |
+
return self._tensorize(data_struct.detach().cpu().numpy()[()])
|
| 143 |
+
if hasattr(data_struct, "__array__") and not isinstance(data_struct, jax.Array):
|
| 144 |
+
data_struct = data_struct.__array__()
|
| 145 |
+
# support for nested types like struct of list of struct
|
| 146 |
+
if isinstance(data_struct, np.ndarray):
|
| 147 |
+
if data_struct.dtype == object: # jax arrays cannot be instantied from an array of objects
|
| 148 |
+
return self._consolidate([self.recursive_tensorize(substruct) for substruct in data_struct])
|
| 149 |
+
elif isinstance(data_struct, (list, tuple)):
|
| 150 |
+
return self._consolidate([self.recursive_tensorize(substruct) for substruct in data_struct])
|
| 151 |
+
return self._tensorize(data_struct)
|
| 152 |
+
|
| 153 |
+
def recursive_tensorize(self, data_struct: dict):
|
| 154 |
+
return map_nested(self._recursive_tensorize, data_struct, map_list=False)
|
| 155 |
+
|
| 156 |
+
def format_row(self, pa_table: pa.Table) -> Mapping:
|
| 157 |
+
row = self.numpy_arrow_extractor().extract_row(pa_table)
|
| 158 |
+
row = self.python_features_decoder.decode_row(row)
|
| 159 |
+
return self.recursive_tensorize(row)
|
| 160 |
+
|
| 161 |
+
def format_column(self, pa_table: pa.Table) -> "jax.Array":
|
| 162 |
+
column = self.numpy_arrow_extractor().extract_column(pa_table)
|
| 163 |
+
column = self.python_features_decoder.decode_column(column, pa_table.column_names[0])
|
| 164 |
+
column = self.recursive_tensorize(column)
|
| 165 |
+
column = self._consolidate(column)
|
| 166 |
+
return column
|
| 167 |
+
|
| 168 |
+
def format_batch(self, pa_table: pa.Table) -> Mapping:
|
| 169 |
+
batch = self.numpy_arrow_extractor().extract_batch(pa_table)
|
| 170 |
+
batch = self.python_features_decoder.decode_batch(batch)
|
| 171 |
+
batch = self.recursive_tensorize(batch)
|
| 172 |
+
for column_name in batch:
|
| 173 |
+
batch[column_name] = self._consolidate(batch[column_name])
|
| 174 |
+
return batch
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/np_formatter.py
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 The HuggingFace Authors.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
import sys
|
| 16 |
+
from collections.abc import Mapping
|
| 17 |
+
|
| 18 |
+
import numpy as np
|
| 19 |
+
import pyarrow as pa
|
| 20 |
+
|
| 21 |
+
from .. import config
|
| 22 |
+
from ..utils.py_utils import map_nested
|
| 23 |
+
from .formatting import TensorFormatter
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
class NumpyFormatter(TensorFormatter[Mapping, np.ndarray, Mapping]):
|
| 27 |
+
def __init__(self, features=None, token_per_repo_id=None, **np_array_kwargs):
|
| 28 |
+
super().__init__(features=features, token_per_repo_id=token_per_repo_id)
|
| 29 |
+
self.np_array_kwargs = np_array_kwargs
|
| 30 |
+
|
| 31 |
+
def _consolidate(self, column):
|
| 32 |
+
if isinstance(column, list):
|
| 33 |
+
if column and all(
|
| 34 |
+
isinstance(x, np.ndarray) and x.shape == column[0].shape and x.dtype == column[0].dtype for x in column
|
| 35 |
+
):
|
| 36 |
+
return np.stack(column)
|
| 37 |
+
else:
|
| 38 |
+
# don't use np.array(column, dtype=object)
|
| 39 |
+
# since it fails in certain cases
|
| 40 |
+
# see https://stackoverflow.com/q/51005699
|
| 41 |
+
out = np.empty(len(column), dtype=object)
|
| 42 |
+
out[:] = column
|
| 43 |
+
return out
|
| 44 |
+
return column
|
| 45 |
+
|
| 46 |
+
def _tensorize(self, value):
|
| 47 |
+
if isinstance(value, (str, bytes, type(None))):
|
| 48 |
+
return value
|
| 49 |
+
elif isinstance(value, (np.character, np.ndarray)) and np.issubdtype(value.dtype, np.character):
|
| 50 |
+
return value
|
| 51 |
+
elif isinstance(value, np.number):
|
| 52 |
+
return value
|
| 53 |
+
|
| 54 |
+
default_dtype = {}
|
| 55 |
+
|
| 56 |
+
if isinstance(value, np.ndarray) and np.issubdtype(value.dtype, np.integer):
|
| 57 |
+
default_dtype = {"dtype": np.int64}
|
| 58 |
+
elif isinstance(value, np.ndarray) and np.issubdtype(value.dtype, np.floating):
|
| 59 |
+
default_dtype = {"dtype": np.float32}
|
| 60 |
+
|
| 61 |
+
if config.PIL_AVAILABLE and "PIL" in sys.modules:
|
| 62 |
+
import PIL.Image
|
| 63 |
+
|
| 64 |
+
if isinstance(value, PIL.Image.Image):
|
| 65 |
+
return np.asarray(value, **self.np_array_kwargs)
|
| 66 |
+
if config.TORCHVISION_AVAILABLE and "torchvision" in sys.modules:
|
| 67 |
+
try:
|
| 68 |
+
from torchvision.io import VideoReader
|
| 69 |
+
|
| 70 |
+
if isinstance(value, VideoReader):
|
| 71 |
+
return value # TODO(QL): set output to np arrays ?
|
| 72 |
+
except ImportError:
|
| 73 |
+
pass
|
| 74 |
+
if config.TORCHCODEC_AVAILABLE and "torchcodec" in sys.modules:
|
| 75 |
+
from torchcodec.decoders import AudioDecoder, VideoDecoder
|
| 76 |
+
|
| 77 |
+
if isinstance(value, (VideoDecoder, AudioDecoder)):
|
| 78 |
+
return value # TODO(QL): set output to np arrays ?
|
| 79 |
+
|
| 80 |
+
return np.asarray(value, **{**default_dtype, **self.np_array_kwargs})
|
| 81 |
+
|
| 82 |
+
def _recursive_tensorize(self, data_struct):
|
| 83 |
+
# support for torch, tf, jax etc.
|
| 84 |
+
if config.TORCH_AVAILABLE and "torch" in sys.modules:
|
| 85 |
+
import torch
|
| 86 |
+
|
| 87 |
+
if isinstance(data_struct, torch.Tensor):
|
| 88 |
+
return self._tensorize(data_struct.detach().cpu().numpy()[()])
|
| 89 |
+
if hasattr(data_struct, "__array__") and not isinstance(data_struct, (np.ndarray, np.character, np.number)):
|
| 90 |
+
data_struct = data_struct.__array__()
|
| 91 |
+
# support for nested types like struct of list of struct
|
| 92 |
+
if isinstance(data_struct, np.ndarray):
|
| 93 |
+
if data_struct.dtype == object:
|
| 94 |
+
return self._consolidate([self.recursive_tensorize(substruct) for substruct in data_struct])
|
| 95 |
+
if isinstance(data_struct, (list, tuple)):
|
| 96 |
+
return self._consolidate([self.recursive_tensorize(substruct) for substruct in data_struct])
|
| 97 |
+
return self._tensorize(data_struct)
|
| 98 |
+
|
| 99 |
+
def recursive_tensorize(self, data_struct: dict):
|
| 100 |
+
return map_nested(self._recursive_tensorize, data_struct, map_list=False)
|
| 101 |
+
|
| 102 |
+
def format_row(self, pa_table: pa.Table) -> Mapping:
|
| 103 |
+
row = self.numpy_arrow_extractor().extract_row(pa_table)
|
| 104 |
+
row = self.python_features_decoder.decode_row(row)
|
| 105 |
+
return self.recursive_tensorize(row)
|
| 106 |
+
|
| 107 |
+
def format_column(self, pa_table: pa.Table) -> np.ndarray:
|
| 108 |
+
column = self.numpy_arrow_extractor().extract_column(pa_table)
|
| 109 |
+
column = self.python_features_decoder.decode_column(column, pa_table.column_names[0])
|
| 110 |
+
column = self.recursive_tensorize(column)
|
| 111 |
+
column = self._consolidate(column)
|
| 112 |
+
return column
|
| 113 |
+
|
| 114 |
+
def format_batch(self, pa_table: pa.Table) -> Mapping:
|
| 115 |
+
batch = self.numpy_arrow_extractor().extract_batch(pa_table)
|
| 116 |
+
batch = self.python_features_decoder.decode_batch(batch)
|
| 117 |
+
batch = self.recursive_tensorize(batch)
|
| 118 |
+
for column_name in batch:
|
| 119 |
+
batch[column_name] = self._consolidate(batch[column_name])
|
| 120 |
+
return batch
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/polars_formatter.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 The HuggingFace Authors.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
import sys
|
| 16 |
+
from functools import partial
|
| 17 |
+
from typing import TYPE_CHECKING, Optional
|
| 18 |
+
|
| 19 |
+
import pyarrow as pa
|
| 20 |
+
|
| 21 |
+
from .. import config
|
| 22 |
+
from ..features import Features
|
| 23 |
+
from ..features.features import decode_nested_example
|
| 24 |
+
from ..utils.py_utils import no_op_if_value_is_null
|
| 25 |
+
from .formatting import BaseArrowExtractor, TableFormatter
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
if TYPE_CHECKING:
|
| 29 |
+
import polars as pl
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class PolarsArrowExtractor(BaseArrowExtractor["pl.DataFrame", "pl.Series", "pl.DataFrame"]):
|
| 33 |
+
def extract_row(self, pa_table: pa.Table) -> "pl.DataFrame":
|
| 34 |
+
if config.POLARS_AVAILABLE:
|
| 35 |
+
if "polars" not in sys.modules:
|
| 36 |
+
import polars
|
| 37 |
+
else:
|
| 38 |
+
polars = sys.modules["polars"]
|
| 39 |
+
|
| 40 |
+
return polars.from_arrow(pa_table.slice(length=1))
|
| 41 |
+
else:
|
| 42 |
+
raise ValueError("Polars needs to be installed to be able to return Polars dataframes.")
|
| 43 |
+
|
| 44 |
+
def extract_column(self, pa_table: pa.Table) -> "pl.Series":
|
| 45 |
+
if config.POLARS_AVAILABLE:
|
| 46 |
+
if "polars" not in sys.modules:
|
| 47 |
+
import polars
|
| 48 |
+
else:
|
| 49 |
+
polars = sys.modules["polars"]
|
| 50 |
+
|
| 51 |
+
return polars.from_arrow(pa_table.select([0]))[pa_table.column_names[0]]
|
| 52 |
+
else:
|
| 53 |
+
raise ValueError("Polars needs to be installed to be able to return Polars dataframes.")
|
| 54 |
+
|
| 55 |
+
def extract_batch(self, pa_table: pa.Table) -> "pl.DataFrame":
|
| 56 |
+
if config.POLARS_AVAILABLE:
|
| 57 |
+
if "polars" not in sys.modules:
|
| 58 |
+
import polars
|
| 59 |
+
else:
|
| 60 |
+
polars = sys.modules["polars"]
|
| 61 |
+
|
| 62 |
+
return polars.from_arrow(pa_table)
|
| 63 |
+
else:
|
| 64 |
+
raise ValueError("Polars needs to be installed to be able to return Polars dataframes.")
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
class PolarsFeaturesDecoder:
|
| 68 |
+
def __init__(self, features: Optional[Features]):
|
| 69 |
+
self.features = features
|
| 70 |
+
import polars as pl # noqa: F401 - import pl at initialization
|
| 71 |
+
|
| 72 |
+
def decode_row(self, row: "pl.DataFrame") -> "pl.DataFrame":
|
| 73 |
+
decode = (
|
| 74 |
+
{
|
| 75 |
+
column_name: no_op_if_value_is_null(partial(decode_nested_example, feature))
|
| 76 |
+
for column_name, feature in self.features.items()
|
| 77 |
+
if self.features._column_requires_decoding[column_name]
|
| 78 |
+
}
|
| 79 |
+
if self.features
|
| 80 |
+
else {}
|
| 81 |
+
)
|
| 82 |
+
if decode:
|
| 83 |
+
row[list(decode.keys())] = row.map_rows(decode)
|
| 84 |
+
return row
|
| 85 |
+
|
| 86 |
+
def decode_column(self, column: "pl.Series", column_name: str) -> "pl.Series":
|
| 87 |
+
decode = (
|
| 88 |
+
no_op_if_value_is_null(partial(decode_nested_example, self.features[column_name]))
|
| 89 |
+
if self.features and column_name in self.features and self.features._column_requires_decoding[column_name]
|
| 90 |
+
else None
|
| 91 |
+
)
|
| 92 |
+
if decode:
|
| 93 |
+
column = column.map_elements(decode)
|
| 94 |
+
return column
|
| 95 |
+
|
| 96 |
+
def decode_batch(self, batch: "pl.DataFrame") -> "pl.DataFrame":
|
| 97 |
+
return self.decode_row(batch)
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
class PolarsFormatter(TableFormatter["pl.DataFrame", "pl.Series", "pl.DataFrame"]):
|
| 101 |
+
table_type = "polars dataframe"
|
| 102 |
+
column_type = "polars series"
|
| 103 |
+
|
| 104 |
+
def __init__(self, features=None, **np_array_kwargs):
|
| 105 |
+
super().__init__(features=features)
|
| 106 |
+
self.np_array_kwargs = np_array_kwargs
|
| 107 |
+
self.polars_arrow_extractor = PolarsArrowExtractor
|
| 108 |
+
self.polars_features_decoder = PolarsFeaturesDecoder(features)
|
| 109 |
+
import polars as pl # noqa: F401 - import pl at initialization
|
| 110 |
+
|
| 111 |
+
def format_row(self, pa_table: pa.Table) -> "pl.DataFrame":
|
| 112 |
+
row = self.polars_arrow_extractor().extract_row(pa_table)
|
| 113 |
+
row = self.polars_features_decoder.decode_row(row)
|
| 114 |
+
return row
|
| 115 |
+
|
| 116 |
+
def format_column(self, pa_table: pa.Table) -> "pl.Series":
|
| 117 |
+
column = self.polars_arrow_extractor().extract_column(pa_table)
|
| 118 |
+
column = self.polars_features_decoder.decode_column(column, pa_table.column_names[0])
|
| 119 |
+
return column
|
| 120 |
+
|
| 121 |
+
def format_batch(self, pa_table: pa.Table) -> "pl.DataFrame":
|
| 122 |
+
row = self.polars_arrow_extractor().extract_batch(pa_table)
|
| 123 |
+
row = self.polars_features_decoder.decode_batch(row)
|
| 124 |
+
return row
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/tf_formatter.py
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 The HuggingFace Authors.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
# Lint as: python3
|
| 16 |
+
import sys
|
| 17 |
+
from collections.abc import Mapping
|
| 18 |
+
from typing import TYPE_CHECKING
|
| 19 |
+
|
| 20 |
+
import numpy as np
|
| 21 |
+
import pyarrow as pa
|
| 22 |
+
|
| 23 |
+
from .. import config
|
| 24 |
+
from ..utils.py_utils import map_nested
|
| 25 |
+
from .formatting import TensorFormatter
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
if TYPE_CHECKING:
|
| 29 |
+
import tensorflow as tf
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class TFFormatter(TensorFormatter[Mapping, "tf.Tensor", Mapping]):
|
| 33 |
+
def __init__(self, features=None, token_per_repo_id=None, **tf_tensor_kwargs):
|
| 34 |
+
super().__init__(features=features, token_per_repo_id=token_per_repo_id)
|
| 35 |
+
self.tf_tensor_kwargs = tf_tensor_kwargs
|
| 36 |
+
import tensorflow as tf # noqa: F401 - import tf at initialization
|
| 37 |
+
|
| 38 |
+
def _consolidate(self, column):
|
| 39 |
+
import tensorflow as tf
|
| 40 |
+
|
| 41 |
+
if isinstance(column, list) and column:
|
| 42 |
+
if all(
|
| 43 |
+
isinstance(x, tf.Tensor) and x.shape == column[0].shape and x.dtype == column[0].dtype for x in column
|
| 44 |
+
):
|
| 45 |
+
return tf.stack(column)
|
| 46 |
+
elif all(
|
| 47 |
+
isinstance(x, (tf.Tensor, tf.RaggedTensor)) and x.ndim == 1 and x.dtype == column[0].dtype
|
| 48 |
+
for x in column
|
| 49 |
+
):
|
| 50 |
+
# only rag 1-D tensors, otherwise some dimensions become ragged even though they were consolidated
|
| 51 |
+
return tf.ragged.stack(column)
|
| 52 |
+
|
| 53 |
+
return column
|
| 54 |
+
|
| 55 |
+
def _tensorize(self, value):
|
| 56 |
+
import tensorflow as tf
|
| 57 |
+
|
| 58 |
+
if value is None:
|
| 59 |
+
return value
|
| 60 |
+
|
| 61 |
+
default_dtype = {}
|
| 62 |
+
|
| 63 |
+
if isinstance(value, (np.number, np.ndarray)) and np.issubdtype(value.dtype, np.integer):
|
| 64 |
+
default_dtype = {"dtype": tf.int64}
|
| 65 |
+
elif isinstance(value, (np.number, np.ndarray)) and np.issubdtype(value.dtype, np.floating):
|
| 66 |
+
default_dtype = {"dtype": tf.float32}
|
| 67 |
+
|
| 68 |
+
if config.PIL_AVAILABLE and "PIL" in sys.modules:
|
| 69 |
+
import PIL.Image
|
| 70 |
+
|
| 71 |
+
if isinstance(value, PIL.Image.Image):
|
| 72 |
+
value = np.asarray(value)
|
| 73 |
+
if config.TORCHVISION_AVAILABLE and "torchvision" in sys.modules:
|
| 74 |
+
try:
|
| 75 |
+
from torchvision.io import VideoReader
|
| 76 |
+
|
| 77 |
+
if isinstance(value, VideoReader):
|
| 78 |
+
return value # TODO(QL): set output to tf tensors ?
|
| 79 |
+
except ImportError:
|
| 80 |
+
pass
|
| 81 |
+
if config.TORCHCODEC_AVAILABLE and "torchcodec" in sys.modules:
|
| 82 |
+
from torchcodec.decoders import AudioDecoder, VideoDecoder
|
| 83 |
+
|
| 84 |
+
if isinstance(value, (VideoDecoder, AudioDecoder)):
|
| 85 |
+
return value # TODO(QL): set output to jax arrays ?
|
| 86 |
+
|
| 87 |
+
return tf.convert_to_tensor(value, **{**default_dtype, **self.tf_tensor_kwargs})
|
| 88 |
+
|
| 89 |
+
def _recursive_tensorize(self, data_struct):
|
| 90 |
+
import tensorflow as tf
|
| 91 |
+
|
| 92 |
+
# support for torch, tf, jax etc.
|
| 93 |
+
if config.TORCH_AVAILABLE and "torch" in sys.modules:
|
| 94 |
+
import torch
|
| 95 |
+
|
| 96 |
+
if isinstance(data_struct, torch.Tensor):
|
| 97 |
+
return self._tensorize(data_struct.detach().cpu().numpy()[()])
|
| 98 |
+
if hasattr(data_struct, "__array__") and not isinstance(data_struct, tf.Tensor):
|
| 99 |
+
data_struct = data_struct.__array__()
|
| 100 |
+
# support for nested types like struct of list of struct
|
| 101 |
+
if isinstance(data_struct, np.ndarray):
|
| 102 |
+
if data_struct.dtype == object: # tf tensors cannot be instantied from an array of objects
|
| 103 |
+
return self._consolidate([self.recursive_tensorize(substruct) for substruct in data_struct])
|
| 104 |
+
elif isinstance(data_struct, (list, tuple)):
|
| 105 |
+
return self._consolidate([self.recursive_tensorize(substruct) for substruct in data_struct])
|
| 106 |
+
return self._tensorize(data_struct)
|
| 107 |
+
|
| 108 |
+
def recursive_tensorize(self, data_struct: dict):
|
| 109 |
+
return map_nested(self._recursive_tensorize, data_struct, map_list=False)
|
| 110 |
+
|
| 111 |
+
def format_row(self, pa_table: pa.Table) -> Mapping:
|
| 112 |
+
row = self.numpy_arrow_extractor().extract_row(pa_table)
|
| 113 |
+
row = self.python_features_decoder.decode_row(row)
|
| 114 |
+
return self.recursive_tensorize(row)
|
| 115 |
+
|
| 116 |
+
def format_column(self, pa_table: pa.Table) -> "tf.Tensor":
|
| 117 |
+
column = self.numpy_arrow_extractor().extract_column(pa_table)
|
| 118 |
+
column = self.python_features_decoder.decode_column(column, pa_table.column_names[0])
|
| 119 |
+
column = self.recursive_tensorize(column)
|
| 120 |
+
column = self._consolidate(column)
|
| 121 |
+
return column
|
| 122 |
+
|
| 123 |
+
def format_batch(self, pa_table: pa.Table) -> Mapping:
|
| 124 |
+
batch = self.numpy_arrow_extractor().extract_batch(pa_table)
|
| 125 |
+
batch = self.python_features_decoder.decode_batch(batch)
|
| 126 |
+
batch = self.recursive_tensorize(batch)
|
| 127 |
+
for column_name in batch:
|
| 128 |
+
batch[column_name] = self._consolidate(batch[column_name])
|
| 129 |
+
return batch
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/torch_formatter.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2020 The HuggingFace Authors.
|
| 2 |
+
#
|
| 3 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
# you may not use this file except in compliance with the License.
|
| 5 |
+
# You may obtain a copy of the License at
|
| 6 |
+
#
|
| 7 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
#
|
| 9 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
# See the License for the specific language governing permissions and
|
| 13 |
+
# limitations under the License.
|
| 14 |
+
|
| 15 |
+
# Lint as: python3
|
| 16 |
+
import sys
|
| 17 |
+
from collections.abc import Mapping
|
| 18 |
+
from typing import TYPE_CHECKING
|
| 19 |
+
|
| 20 |
+
import numpy as np
|
| 21 |
+
import pyarrow as pa
|
| 22 |
+
|
| 23 |
+
from .. import config
|
| 24 |
+
from ..utils.py_utils import map_nested
|
| 25 |
+
from .formatting import TensorFormatter
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
if TYPE_CHECKING:
|
| 29 |
+
import torch
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class TorchFormatter(TensorFormatter[Mapping, "torch.Tensor", Mapping]):
|
| 33 |
+
def __init__(self, features=None, token_per_repo_id=None, **torch_tensor_kwargs):
|
| 34 |
+
super().__init__(features=features, token_per_repo_id=token_per_repo_id)
|
| 35 |
+
self.torch_tensor_kwargs = torch_tensor_kwargs
|
| 36 |
+
import torch # noqa import torch at initialization
|
| 37 |
+
|
| 38 |
+
def _consolidate(self, column):
|
| 39 |
+
import torch
|
| 40 |
+
|
| 41 |
+
if isinstance(column, list) and column:
|
| 42 |
+
if all(
|
| 43 |
+
isinstance(x, torch.Tensor) and x.shape == column[0].shape and x.dtype == column[0].dtype
|
| 44 |
+
for x in column
|
| 45 |
+
):
|
| 46 |
+
return torch.stack(column)
|
| 47 |
+
return column
|
| 48 |
+
|
| 49 |
+
def _tensorize(self, value):
|
| 50 |
+
import torch
|
| 51 |
+
|
| 52 |
+
if isinstance(value, (str, bytes, type(None))):
|
| 53 |
+
return value
|
| 54 |
+
elif isinstance(value, (np.character, np.ndarray)) and np.issubdtype(value.dtype, np.character):
|
| 55 |
+
return value.tolist()
|
| 56 |
+
|
| 57 |
+
default_dtype = {}
|
| 58 |
+
|
| 59 |
+
if isinstance(value, (np.number, np.ndarray)) and np.issubdtype(value.dtype, np.integer):
|
| 60 |
+
default_dtype = {"dtype": torch.int64}
|
| 61 |
+
|
| 62 |
+
# Convert dtype to np.int64 if it's either np.uint16 or np.uint32 to ensure compatibility.
|
| 63 |
+
# np.uint64 is excluded from this conversion as there is no compatible PyTorch dtype that can handle it without loss.
|
| 64 |
+
if value.dtype in [np.uint16, np.uint32]:
|
| 65 |
+
value = value.astype(np.int64)
|
| 66 |
+
|
| 67 |
+
elif isinstance(value, (np.number, np.ndarray)) and np.issubdtype(value.dtype, np.floating):
|
| 68 |
+
default_dtype = {"dtype": torch.float32}
|
| 69 |
+
|
| 70 |
+
if config.PIL_AVAILABLE and "PIL" in sys.modules:
|
| 71 |
+
import PIL.Image
|
| 72 |
+
|
| 73 |
+
if isinstance(value, PIL.Image.Image):
|
| 74 |
+
value = np.asarray(value)
|
| 75 |
+
if value.ndim == 2:
|
| 76 |
+
value = value[:, :, np.newaxis]
|
| 77 |
+
|
| 78 |
+
value = value.transpose((2, 0, 1))
|
| 79 |
+
if config.TORCHVISION_AVAILABLE and "torchvision" in sys.modules:
|
| 80 |
+
try:
|
| 81 |
+
from torchvision.io import VideoReader
|
| 82 |
+
|
| 83 |
+
if isinstance(value, VideoReader):
|
| 84 |
+
return value # TODO(QL): set output to torch tensors ?
|
| 85 |
+
except ImportError:
|
| 86 |
+
pass
|
| 87 |
+
if config.TORCHCODEC_AVAILABLE and "torchcodec" in sys.modules:
|
| 88 |
+
from torchcodec.decoders import AudioDecoder, VideoDecoder
|
| 89 |
+
|
| 90 |
+
if isinstance(value, (VideoDecoder, AudioDecoder)):
|
| 91 |
+
return value # TODO(QL): set output to jax arrays ?
|
| 92 |
+
|
| 93 |
+
return torch.tensor(value, **{**default_dtype, **self.torch_tensor_kwargs})
|
| 94 |
+
|
| 95 |
+
def _recursive_tensorize(self, data_struct):
|
| 96 |
+
import torch
|
| 97 |
+
|
| 98 |
+
# support for torch, tf, jax etc.
|
| 99 |
+
if hasattr(data_struct, "__array__") and not isinstance(data_struct, torch.Tensor):
|
| 100 |
+
data_struct = data_struct.__array__()
|
| 101 |
+
# support for nested types like struct of list of struct
|
| 102 |
+
if isinstance(data_struct, np.ndarray):
|
| 103 |
+
if data_struct.dtype == object: # torch tensors cannot be instantied from an array of objects
|
| 104 |
+
return self._consolidate([self.recursive_tensorize(substruct) for substruct in data_struct])
|
| 105 |
+
elif isinstance(data_struct, (list, tuple)):
|
| 106 |
+
return self._consolidate([self.recursive_tensorize(substruct) for substruct in data_struct])
|
| 107 |
+
return self._tensorize(data_struct)
|
| 108 |
+
|
| 109 |
+
def recursive_tensorize(self, data_struct: dict):
|
| 110 |
+
return map_nested(self._recursive_tensorize, data_struct, map_list=False)
|
| 111 |
+
|
| 112 |
+
def format_row(self, pa_table: pa.Table) -> Mapping:
|
| 113 |
+
row = self.numpy_arrow_extractor().extract_row(pa_table)
|
| 114 |
+
row = self.python_features_decoder.decode_row(row)
|
| 115 |
+
return self.recursive_tensorize(row)
|
| 116 |
+
|
| 117 |
+
def format_column(self, pa_table: pa.Table) -> "torch.Tensor":
|
| 118 |
+
column = self.numpy_arrow_extractor().extract_column(pa_table)
|
| 119 |
+
column = self.python_features_decoder.decode_column(column, pa_table.column_names[0])
|
| 120 |
+
column = self.recursive_tensorize(column)
|
| 121 |
+
column = self._consolidate(column)
|
| 122 |
+
return column
|
| 123 |
+
|
| 124 |
+
def format_batch(self, pa_table: pa.Table) -> Mapping:
|
| 125 |
+
batch = self.numpy_arrow_extractor().extract_batch(pa_table)
|
| 126 |
+
batch = self.python_features_decoder.decode_batch(batch)
|
| 127 |
+
batch = self.recursive_tensorize(batch)
|
| 128 |
+
for column_name in batch:
|
| 129 |
+
batch[column_name] = self._consolidate(batch[column_name])
|
| 130 |
+
return batch
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/abc.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from abc import ABC, abstractmethod
|
| 2 |
+
from typing import Optional, Union
|
| 3 |
+
|
| 4 |
+
from .. import Dataset, DatasetDict, Features, IterableDataset, IterableDatasetDict, NamedSplit
|
| 5 |
+
from ..utils.typing import NestedDataStructureLike, PathLike
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class AbstractDatasetReader(ABC):
|
| 9 |
+
def __init__(
|
| 10 |
+
self,
|
| 11 |
+
path_or_paths: Optional[NestedDataStructureLike[PathLike]] = None,
|
| 12 |
+
split: Optional[NamedSplit] = None,
|
| 13 |
+
features: Optional[Features] = None,
|
| 14 |
+
cache_dir: str = None,
|
| 15 |
+
keep_in_memory: bool = False,
|
| 16 |
+
streaming: bool = False,
|
| 17 |
+
num_proc: Optional[int] = None,
|
| 18 |
+
**kwargs,
|
| 19 |
+
):
|
| 20 |
+
self.path_or_paths = path_or_paths
|
| 21 |
+
self.split = split if split or isinstance(path_or_paths, dict) else "train"
|
| 22 |
+
self.features = features
|
| 23 |
+
self.cache_dir = cache_dir
|
| 24 |
+
self.keep_in_memory = keep_in_memory
|
| 25 |
+
self.streaming = streaming
|
| 26 |
+
self.num_proc = num_proc
|
| 27 |
+
self.kwargs = kwargs
|
| 28 |
+
|
| 29 |
+
@abstractmethod
|
| 30 |
+
def read(self) -> Union[Dataset, DatasetDict, IterableDataset, IterableDatasetDict]:
|
| 31 |
+
pass
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class AbstractDatasetInputStream(ABC):
|
| 35 |
+
def __init__(
|
| 36 |
+
self,
|
| 37 |
+
features: Optional[Features] = None,
|
| 38 |
+
cache_dir: str = None,
|
| 39 |
+
keep_in_memory: bool = False,
|
| 40 |
+
streaming: bool = False,
|
| 41 |
+
num_proc: Optional[int] = None,
|
| 42 |
+
**kwargs,
|
| 43 |
+
):
|
| 44 |
+
self.features = features
|
| 45 |
+
self.cache_dir = cache_dir
|
| 46 |
+
self.keep_in_memory = keep_in_memory
|
| 47 |
+
self.streaming = streaming
|
| 48 |
+
self.num_proc = num_proc
|
| 49 |
+
self.kwargs = kwargs
|
| 50 |
+
|
| 51 |
+
@abstractmethod
|
| 52 |
+
def read(self) -> Union[Dataset, IterableDataset]:
|
| 53 |
+
pass
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/generator.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Callable, Optional
|
| 2 |
+
|
| 3 |
+
from .. import Features, NamedSplit, Split
|
| 4 |
+
from ..packaged_modules.generator.generator import Generator
|
| 5 |
+
from .abc import AbstractDatasetInputStream
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class GeneratorDatasetInputStream(AbstractDatasetInputStream):
|
| 9 |
+
def __init__(
|
| 10 |
+
self,
|
| 11 |
+
generator: Callable,
|
| 12 |
+
features: Optional[Features] = None,
|
| 13 |
+
cache_dir: str = None,
|
| 14 |
+
keep_in_memory: bool = False,
|
| 15 |
+
streaming: bool = False,
|
| 16 |
+
gen_kwargs: Optional[dict] = None,
|
| 17 |
+
num_proc: Optional[int] = None,
|
| 18 |
+
split: NamedSplit = Split.TRAIN,
|
| 19 |
+
fingerprint: Optional[str] = None,
|
| 20 |
+
**kwargs,
|
| 21 |
+
):
|
| 22 |
+
super().__init__(
|
| 23 |
+
features=features,
|
| 24 |
+
cache_dir=cache_dir,
|
| 25 |
+
keep_in_memory=keep_in_memory,
|
| 26 |
+
streaming=streaming,
|
| 27 |
+
num_proc=num_proc,
|
| 28 |
+
**kwargs,
|
| 29 |
+
)
|
| 30 |
+
self.builder = Generator(
|
| 31 |
+
cache_dir=cache_dir,
|
| 32 |
+
features=features,
|
| 33 |
+
generator=generator,
|
| 34 |
+
gen_kwargs=gen_kwargs,
|
| 35 |
+
split=split,
|
| 36 |
+
config_id="default-fingerprint=" + fingerprint if fingerprint else None,
|
| 37 |
+
**kwargs,
|
| 38 |
+
)
|
| 39 |
+
self.fingerprint = fingerprint
|
| 40 |
+
|
| 41 |
+
def read(self):
|
| 42 |
+
# Build iterable dataset
|
| 43 |
+
if self.streaming:
|
| 44 |
+
dataset = self.builder.as_streaming_dataset(split=self.builder.config.split)
|
| 45 |
+
# Build regular (map-style) dataset
|
| 46 |
+
else:
|
| 47 |
+
download_config = None
|
| 48 |
+
download_mode = None
|
| 49 |
+
verification_mode = None
|
| 50 |
+
base_path = None
|
| 51 |
+
|
| 52 |
+
self.builder.download_and_prepare(
|
| 53 |
+
download_config=download_config,
|
| 54 |
+
download_mode=download_mode,
|
| 55 |
+
verification_mode=verification_mode,
|
| 56 |
+
base_path=base_path,
|
| 57 |
+
num_proc=self.num_proc,
|
| 58 |
+
)
|
| 59 |
+
dataset = self.builder.as_dataset(split=self.builder.config.split, in_memory=self.keep_in_memory)
|
| 60 |
+
if self.fingerprint:
|
| 61 |
+
dataset._fingerprint = self.fingerprint
|
| 62 |
+
return dataset
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/parquet.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
from typing import BinaryIO, Optional, Union
|
| 4 |
+
|
| 5 |
+
import fsspec
|
| 6 |
+
import pyarrow.parquet as pq
|
| 7 |
+
|
| 8 |
+
from .. import Dataset, Features, NamedSplit, config
|
| 9 |
+
from ..arrow_writer import get_writer_batch_size_from_data_size, get_writer_batch_size_from_features
|
| 10 |
+
from ..features.features import require_storage_embed
|
| 11 |
+
from ..formatting import query_table
|
| 12 |
+
from ..packaged_modules import _PACKAGED_DATASETS_MODULES
|
| 13 |
+
from ..packaged_modules.parquet.parquet import Parquet
|
| 14 |
+
from ..utils import tqdm as hf_tqdm
|
| 15 |
+
from ..utils.typing import NestedDataStructureLike, PathLike
|
| 16 |
+
from .abc import AbstractDatasetReader
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class ParquetDatasetReader(AbstractDatasetReader):
|
| 20 |
+
def __init__(
|
| 21 |
+
self,
|
| 22 |
+
path_or_paths: NestedDataStructureLike[PathLike],
|
| 23 |
+
split: Optional[NamedSplit] = None,
|
| 24 |
+
features: Optional[Features] = None,
|
| 25 |
+
cache_dir: str = None,
|
| 26 |
+
keep_in_memory: bool = False,
|
| 27 |
+
streaming: bool = False,
|
| 28 |
+
num_proc: Optional[int] = None,
|
| 29 |
+
**kwargs,
|
| 30 |
+
):
|
| 31 |
+
super().__init__(
|
| 32 |
+
path_or_paths,
|
| 33 |
+
split=split,
|
| 34 |
+
features=features,
|
| 35 |
+
cache_dir=cache_dir,
|
| 36 |
+
keep_in_memory=keep_in_memory,
|
| 37 |
+
streaming=streaming,
|
| 38 |
+
num_proc=num_proc,
|
| 39 |
+
**kwargs,
|
| 40 |
+
)
|
| 41 |
+
path_or_paths = path_or_paths if isinstance(path_or_paths, dict) else {self.split: path_or_paths}
|
| 42 |
+
hash = _PACKAGED_DATASETS_MODULES["parquet"][1]
|
| 43 |
+
self.builder = Parquet(
|
| 44 |
+
cache_dir=cache_dir,
|
| 45 |
+
data_files=path_or_paths,
|
| 46 |
+
features=features,
|
| 47 |
+
hash=hash,
|
| 48 |
+
**kwargs,
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
def read(self):
|
| 52 |
+
# Build iterable dataset
|
| 53 |
+
if self.streaming:
|
| 54 |
+
dataset = self.builder.as_streaming_dataset(split=self.split)
|
| 55 |
+
# Build regular (map-style) dataset
|
| 56 |
+
else:
|
| 57 |
+
download_config = None
|
| 58 |
+
download_mode = None
|
| 59 |
+
verification_mode = None
|
| 60 |
+
base_path = None
|
| 61 |
+
|
| 62 |
+
self.builder.download_and_prepare(
|
| 63 |
+
download_config=download_config,
|
| 64 |
+
download_mode=download_mode,
|
| 65 |
+
verification_mode=verification_mode,
|
| 66 |
+
base_path=base_path,
|
| 67 |
+
num_proc=self.num_proc,
|
| 68 |
+
)
|
| 69 |
+
dataset = self.builder.as_dataset(split=self.split, in_memory=self.keep_in_memory)
|
| 70 |
+
return dataset
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
class ParquetDatasetWriter:
|
| 74 |
+
def __init__(
|
| 75 |
+
self,
|
| 76 |
+
dataset: Dataset,
|
| 77 |
+
path_or_buf: Union[PathLike, BinaryIO],
|
| 78 |
+
batch_size: Optional[int] = None,
|
| 79 |
+
storage_options: Optional[dict] = None,
|
| 80 |
+
use_content_defined_chunking: Union[bool, dict] = True,
|
| 81 |
+
write_page_index: bool = True,
|
| 82 |
+
**parquet_writer_kwargs,
|
| 83 |
+
):
|
| 84 |
+
self.dataset = dataset
|
| 85 |
+
self.path_or_buf = path_or_buf
|
| 86 |
+
self.batch_size = (
|
| 87 |
+
batch_size
|
| 88 |
+
or get_writer_batch_size_from_features(dataset.features)
|
| 89 |
+
or get_writer_batch_size_from_data_size(len(dataset), dataset._estimate_nbytes())
|
| 90 |
+
)
|
| 91 |
+
self.storage_options = storage_options or {}
|
| 92 |
+
self.parquet_writer_kwargs = parquet_writer_kwargs
|
| 93 |
+
if use_content_defined_chunking is True:
|
| 94 |
+
use_content_defined_chunking = config.DEFAULT_CDC_OPTIONS
|
| 95 |
+
self.use_content_defined_chunking = use_content_defined_chunking
|
| 96 |
+
self.write_page_index = write_page_index
|
| 97 |
+
|
| 98 |
+
def write(self) -> int:
|
| 99 |
+
if isinstance(self.path_or_buf, (str, bytes, os.PathLike)):
|
| 100 |
+
with fsspec.open(self.path_or_buf, "wb", **(self.storage_options or {})) as buffer:
|
| 101 |
+
written = self._write(
|
| 102 |
+
file_obj=buffer,
|
| 103 |
+
batch_size=self.batch_size,
|
| 104 |
+
**self.parquet_writer_kwargs,
|
| 105 |
+
)
|
| 106 |
+
else:
|
| 107 |
+
written = self._write(
|
| 108 |
+
file_obj=self.path_or_buf,
|
| 109 |
+
batch_size=self.batch_size,
|
| 110 |
+
**self.parquet_writer_kwargs,
|
| 111 |
+
)
|
| 112 |
+
return written
|
| 113 |
+
|
| 114 |
+
def _write(self, file_obj: BinaryIO, batch_size: int, **parquet_writer_kwargs) -> int:
|
| 115 |
+
"""Writes the pyarrow table as Parquet to a binary file handle.
|
| 116 |
+
|
| 117 |
+
Caller is responsible for opening and closing the handle.
|
| 118 |
+
"""
|
| 119 |
+
written = 0
|
| 120 |
+
_ = parquet_writer_kwargs.pop("path_or_buf", None)
|
| 121 |
+
schema = self.dataset.features.arrow_schema
|
| 122 |
+
|
| 123 |
+
writer = pq.ParquetWriter(
|
| 124 |
+
file_obj,
|
| 125 |
+
schema=schema,
|
| 126 |
+
use_content_defined_chunking=self.use_content_defined_chunking,
|
| 127 |
+
write_page_index=self.write_page_index,
|
| 128 |
+
compression={
|
| 129 |
+
col: "none" if require_storage_embed(feature) else "snappy"
|
| 130 |
+
for col, feature in self.dataset.features.items()
|
| 131 |
+
},
|
| 132 |
+
use_dictionary=[
|
| 133 |
+
col for col, feature in self.dataset.features.items() if not require_storage_embed(feature)
|
| 134 |
+
],
|
| 135 |
+
column_encoding={
|
| 136 |
+
col: "PLAIN" for col, feature in self.dataset.features.items() if require_storage_embed(feature)
|
| 137 |
+
},
|
| 138 |
+
**parquet_writer_kwargs,
|
| 139 |
+
)
|
| 140 |
+
|
| 141 |
+
for offset in hf_tqdm(
|
| 142 |
+
range(0, len(self.dataset), batch_size),
|
| 143 |
+
unit="ba",
|
| 144 |
+
desc="Creating parquet from Arrow format",
|
| 145 |
+
):
|
| 146 |
+
batch = query_table(
|
| 147 |
+
table=self.dataset._data,
|
| 148 |
+
key=slice(offset, offset + batch_size),
|
| 149 |
+
indices=self.dataset._indices,
|
| 150 |
+
)
|
| 151 |
+
writer.write_table(batch)
|
| 152 |
+
written += batch.nbytes
|
| 153 |
+
|
| 154 |
+
# TODO(kszucs): we may want to persist multiple parameters
|
| 155 |
+
if self.use_content_defined_chunking is not False:
|
| 156 |
+
writer.add_key_value_metadata({"content_defined_chunking": json.dumps(self.use_content_defined_chunking)})
|
| 157 |
+
|
| 158 |
+
writer.close()
|
| 159 |
+
return written
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/spark.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
import pyspark
|
| 4 |
+
|
| 5 |
+
from .. import Features, NamedSplit
|
| 6 |
+
from ..download import DownloadMode
|
| 7 |
+
from ..packaged_modules.spark.spark import Spark
|
| 8 |
+
from .abc import AbstractDatasetReader
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class SparkDatasetReader(AbstractDatasetReader):
|
| 12 |
+
"""A dataset reader that reads from a Spark DataFrame.
|
| 13 |
+
|
| 14 |
+
When caching, cache materialization is parallelized over Spark; an NFS that is accessible to the driver must be
|
| 15 |
+
provided. Streaming is not currently supported.
|
| 16 |
+
"""
|
| 17 |
+
|
| 18 |
+
def __init__(
|
| 19 |
+
self,
|
| 20 |
+
df: pyspark.sql.DataFrame,
|
| 21 |
+
split: Optional[NamedSplit] = None,
|
| 22 |
+
features: Optional[Features] = None,
|
| 23 |
+
streaming: bool = True,
|
| 24 |
+
cache_dir: str = None,
|
| 25 |
+
keep_in_memory: bool = False,
|
| 26 |
+
working_dir: str = None,
|
| 27 |
+
load_from_cache_file: bool = True,
|
| 28 |
+
file_format: str = "arrow",
|
| 29 |
+
**kwargs,
|
| 30 |
+
):
|
| 31 |
+
super().__init__(
|
| 32 |
+
split=split,
|
| 33 |
+
features=features,
|
| 34 |
+
cache_dir=cache_dir,
|
| 35 |
+
keep_in_memory=keep_in_memory,
|
| 36 |
+
streaming=streaming,
|
| 37 |
+
**kwargs,
|
| 38 |
+
)
|
| 39 |
+
self._load_from_cache_file = load_from_cache_file
|
| 40 |
+
self._file_format = file_format
|
| 41 |
+
self.builder = Spark(
|
| 42 |
+
df=df,
|
| 43 |
+
features=features,
|
| 44 |
+
cache_dir=cache_dir,
|
| 45 |
+
working_dir=working_dir,
|
| 46 |
+
**kwargs,
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
def read(self):
|
| 50 |
+
if self.streaming:
|
| 51 |
+
return self.builder.as_streaming_dataset(split=self.split)
|
| 52 |
+
download_mode = None if self._load_from_cache_file else DownloadMode.FORCE_REDOWNLOAD
|
| 53 |
+
self.builder.download_and_prepare(
|
| 54 |
+
download_mode=download_mode,
|
| 55 |
+
file_format=self._file_format,
|
| 56 |
+
)
|
| 57 |
+
return self.builder.as_dataset(split=self.split)
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/text.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional
|
| 2 |
+
|
| 3 |
+
from .. import Features, NamedSplit
|
| 4 |
+
from ..packaged_modules.text.text import Text
|
| 5 |
+
from ..utils.typing import NestedDataStructureLike, PathLike
|
| 6 |
+
from .abc import AbstractDatasetReader
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class TextDatasetReader(AbstractDatasetReader):
|
| 10 |
+
def __init__(
|
| 11 |
+
self,
|
| 12 |
+
path_or_paths: NestedDataStructureLike[PathLike],
|
| 13 |
+
split: Optional[NamedSplit] = None,
|
| 14 |
+
features: Optional[Features] = None,
|
| 15 |
+
cache_dir: str = None,
|
| 16 |
+
keep_in_memory: bool = False,
|
| 17 |
+
streaming: bool = False,
|
| 18 |
+
num_proc: Optional[int] = None,
|
| 19 |
+
**kwargs,
|
| 20 |
+
):
|
| 21 |
+
super().__init__(
|
| 22 |
+
path_or_paths,
|
| 23 |
+
split=split,
|
| 24 |
+
features=features,
|
| 25 |
+
cache_dir=cache_dir,
|
| 26 |
+
keep_in_memory=keep_in_memory,
|
| 27 |
+
streaming=streaming,
|
| 28 |
+
num_proc=num_proc,
|
| 29 |
+
**kwargs,
|
| 30 |
+
)
|
| 31 |
+
path_or_paths = path_or_paths if isinstance(path_or_paths, dict) else {self.split: path_or_paths}
|
| 32 |
+
self.builder = Text(
|
| 33 |
+
cache_dir=cache_dir,
|
| 34 |
+
data_files=path_or_paths,
|
| 35 |
+
features=features,
|
| 36 |
+
**kwargs,
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
def read(self):
|
| 40 |
+
# Build iterable dataset
|
| 41 |
+
if self.streaming:
|
| 42 |
+
dataset = self.builder.as_streaming_dataset(split=self.split)
|
| 43 |
+
# Build regular (map-style) dataset
|
| 44 |
+
else:
|
| 45 |
+
download_config = None
|
| 46 |
+
download_mode = None
|
| 47 |
+
verification_mode = None
|
| 48 |
+
base_path = None
|
| 49 |
+
|
| 50 |
+
self.builder.download_and_prepare(
|
| 51 |
+
download_config=download_config,
|
| 52 |
+
download_mode=download_mode,
|
| 53 |
+
verification_mode=verification_mode,
|
| 54 |
+
base_path=base_path,
|
| 55 |
+
num_proc=self.num_proc,
|
| 56 |
+
)
|
| 57 |
+
dataset = self.builder.as_dataset(split=self.split, in_memory=self.keep_in_memory)
|
| 58 |
+
return dataset
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/arrow/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/arrow/arrow.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from dataclasses import dataclass
|
| 2 |
+
from typing import Optional
|
| 3 |
+
|
| 4 |
+
import pyarrow as pa
|
| 5 |
+
|
| 6 |
+
import datasets
|
| 7 |
+
from datasets.builder import Key
|
| 8 |
+
from datasets.table import table_cast
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
@dataclass
|
| 15 |
+
class ArrowConfig(datasets.BuilderConfig):
|
| 16 |
+
"""BuilderConfig for Arrow."""
|
| 17 |
+
|
| 18 |
+
features: Optional[datasets.Features] = None
|
| 19 |
+
|
| 20 |
+
def __post_init__(self):
|
| 21 |
+
super().__post_init__()
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class Arrow(datasets.ArrowBasedBuilder):
|
| 25 |
+
BUILDER_CONFIG_CLASS = ArrowConfig
|
| 26 |
+
|
| 27 |
+
def _info(self):
|
| 28 |
+
return datasets.DatasetInfo(features=self.config.features)
|
| 29 |
+
|
| 30 |
+
def _split_generators(self, dl_manager):
|
| 31 |
+
"""We handle string, list and dicts in datafiles"""
|
| 32 |
+
if not self.config.data_files:
|
| 33 |
+
raise ValueError(f"At least one data file must be specified, but got data_files={self.config.data_files}")
|
| 34 |
+
data_files = dl_manager.download(self.config.data_files)
|
| 35 |
+
splits = []
|
| 36 |
+
for split_name, files in data_files.items():
|
| 37 |
+
# Infer features if they are stored in the arrow schema
|
| 38 |
+
if self.info.features is None:
|
| 39 |
+
for file in files:
|
| 40 |
+
with open(file, "rb") as f:
|
| 41 |
+
try:
|
| 42 |
+
reader = pa.ipc.open_stream(f)
|
| 43 |
+
except (OSError, pa.lib.ArrowInvalid):
|
| 44 |
+
reader = pa.ipc.open_file(f)
|
| 45 |
+
self.info.features = datasets.Features.from_arrow_schema(reader.schema)
|
| 46 |
+
break
|
| 47 |
+
splits.append(datasets.SplitGenerator(name=split_name, gen_kwargs={"files": files}))
|
| 48 |
+
return splits
|
| 49 |
+
|
| 50 |
+
def _cast_table(self, pa_table: pa.Table) -> pa.Table:
|
| 51 |
+
if self.info.features is not None:
|
| 52 |
+
# more expensive cast to support nested features with keys in a different order
|
| 53 |
+
# allows str <-> int/float or str to Audio for example
|
| 54 |
+
pa_table = table_cast(pa_table, self.info.features.arrow_schema)
|
| 55 |
+
return pa_table
|
| 56 |
+
|
| 57 |
+
def _generate_shards(self, files):
|
| 58 |
+
yield from files
|
| 59 |
+
|
| 60 |
+
def _generate_tables(self, files):
|
| 61 |
+
for file_idx, file in enumerate(files):
|
| 62 |
+
with open(file, "rb") as f:
|
| 63 |
+
try:
|
| 64 |
+
try:
|
| 65 |
+
batches = pa.ipc.open_stream(f)
|
| 66 |
+
except (OSError, pa.lib.ArrowInvalid):
|
| 67 |
+
reader = pa.ipc.open_file(f)
|
| 68 |
+
batches = (reader.get_batch(i) for i in range(reader.num_record_batches))
|
| 69 |
+
for batch_idx, record_batch in enumerate(batches):
|
| 70 |
+
pa_table = pa.Table.from_batches([record_batch])
|
| 71 |
+
# Uncomment for debugging (will print the Arrow table size and elements)
|
| 72 |
+
# logger.warning(f"pa_table: {pa_table} num rows: {pa_table.num_rows}")
|
| 73 |
+
# logger.warning('\n'.join(str(pa_table.slice(i, 1).to_pydict()) for i in range(pa_table.num_rows)))
|
| 74 |
+
yield Key(file_idx, batch_idx), self._cast_table(pa_table)
|
| 75 |
+
except ValueError as e:
|
| 76 |
+
logger.error(f"Failed to read file '{file}' with error {type(e)}: {e}")
|
| 77 |
+
raise
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/audiofolder/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/audiofolder/audiofolder.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import datasets
|
| 2 |
+
|
| 3 |
+
from ..folder_based_builder import folder_based_builder
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class AudioFolderConfig(folder_based_builder.FolderBasedBuilderConfig):
|
| 10 |
+
"""Builder Config for AudioFolder."""
|
| 11 |
+
|
| 12 |
+
drop_labels: bool = None
|
| 13 |
+
drop_metadata: bool = None
|
| 14 |
+
|
| 15 |
+
def __post_init__(self):
|
| 16 |
+
super().__post_init__()
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class AudioFolder(folder_based_builder.FolderBasedBuilder):
|
| 20 |
+
BASE_FEATURE = datasets.Audio
|
| 21 |
+
BASE_COLUMN_NAME = "audio"
|
| 22 |
+
BUILDER_CONFIG_CLASS = AudioFolderConfig
|
| 23 |
+
EXTENSIONS: list[str] # definition at the bottom of the script
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
# Obtained with:
|
| 27 |
+
# ```
|
| 28 |
+
# import soundfile as sf
|
| 29 |
+
#
|
| 30 |
+
# AUDIO_EXTENSIONS = [f".{format.lower()}" for format in sf.available_formats().keys()]
|
| 31 |
+
#
|
| 32 |
+
# # .opus decoding is supported if libsndfile >= 1.0.31:
|
| 33 |
+
# AUDIO_EXTENSIONS.extend([".opus"])
|
| 34 |
+
# ```
|
| 35 |
+
# We intentionally did not run this code on launch because:
|
| 36 |
+
# (1) Soundfile was an optional dependency, so importing it in global namespace is not allowed
|
| 37 |
+
# (2) To ensure the list of supported extensions is deterministic
|
| 38 |
+
# (3) We use TorchCodec now anyways instead of Soundfile
|
| 39 |
+
AUDIO_EXTENSIONS = [
|
| 40 |
+
".aiff",
|
| 41 |
+
".au",
|
| 42 |
+
".avr",
|
| 43 |
+
".caf",
|
| 44 |
+
".flac",
|
| 45 |
+
".htk",
|
| 46 |
+
".svx",
|
| 47 |
+
".mat4",
|
| 48 |
+
".mat5",
|
| 49 |
+
".mpc2k",
|
| 50 |
+
".ogg",
|
| 51 |
+
".paf",
|
| 52 |
+
".pvf",
|
| 53 |
+
".raw",
|
| 54 |
+
".rf64",
|
| 55 |
+
".sd2",
|
| 56 |
+
".sds",
|
| 57 |
+
".ircam",
|
| 58 |
+
".voc",
|
| 59 |
+
".w64",
|
| 60 |
+
".wav",
|
| 61 |
+
".nist",
|
| 62 |
+
".wavex",
|
| 63 |
+
".wve",
|
| 64 |
+
".xi",
|
| 65 |
+
".mp3",
|
| 66 |
+
".opus",
|
| 67 |
+
".3gp",
|
| 68 |
+
".3g2",
|
| 69 |
+
".avi",
|
| 70 |
+
".asf",
|
| 71 |
+
".flv",
|
| 72 |
+
".mp4",
|
| 73 |
+
".mov",
|
| 74 |
+
".m4v",
|
| 75 |
+
".mkv",
|
| 76 |
+
".mpg",
|
| 77 |
+
".webm",
|
| 78 |
+
".f4v",
|
| 79 |
+
".wmv",
|
| 80 |
+
".wma",
|
| 81 |
+
".ogg",
|
| 82 |
+
".ogm",
|
| 83 |
+
".mxf",
|
| 84 |
+
".nut",
|
| 85 |
+
]
|
| 86 |
+
AudioFolder.EXTENSIONS = AUDIO_EXTENSIONS
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/cache/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/cache/cache.py
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import glob
|
| 2 |
+
import json
|
| 3 |
+
import os
|
| 4 |
+
import shutil
|
| 5 |
+
import time
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
from typing import Optional, Union
|
| 8 |
+
|
| 9 |
+
import pyarrow as pa
|
| 10 |
+
|
| 11 |
+
import datasets
|
| 12 |
+
import datasets.config
|
| 13 |
+
import datasets.data_files
|
| 14 |
+
from datasets.builder import Key
|
| 15 |
+
from datasets.naming import camelcase_to_snakecase, filenames_for_dataset_split
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def _get_modification_time(cached_directory_path):
|
| 22 |
+
return (Path(cached_directory_path)).stat().st_mtime
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def _find_hash_in_cache(
|
| 26 |
+
dataset_name: str,
|
| 27 |
+
config_name: Optional[str],
|
| 28 |
+
cache_dir: Optional[str],
|
| 29 |
+
config_kwargs: dict,
|
| 30 |
+
custom_features: Optional[datasets.Features],
|
| 31 |
+
) -> tuple[str, str, str]:
|
| 32 |
+
if config_name or config_kwargs or custom_features:
|
| 33 |
+
config_id = datasets.BuilderConfig(config_name or "default").create_config_id(
|
| 34 |
+
config_kwargs=config_kwargs, custom_features=custom_features
|
| 35 |
+
)
|
| 36 |
+
else:
|
| 37 |
+
config_id = None
|
| 38 |
+
cache_dir = os.path.expanduser(str(cache_dir or datasets.config.HF_DATASETS_CACHE))
|
| 39 |
+
namespace_and_dataset_name = dataset_name.split("/")
|
| 40 |
+
namespace_and_dataset_name[-1] = camelcase_to_snakecase(namespace_and_dataset_name[-1])
|
| 41 |
+
cached_relative_path = "___".join(namespace_and_dataset_name)
|
| 42 |
+
cached_datasets_directory_path_root = os.path.join(cache_dir, cached_relative_path)
|
| 43 |
+
cached_directory_paths = [
|
| 44 |
+
cached_directory_path
|
| 45 |
+
for cached_directory_path in glob.glob(
|
| 46 |
+
os.path.join(cached_datasets_directory_path_root, config_id or "*", "*", "*")
|
| 47 |
+
)
|
| 48 |
+
if os.path.isdir(cached_directory_path)
|
| 49 |
+
and (
|
| 50 |
+
config_kwargs
|
| 51 |
+
or custom_features
|
| 52 |
+
or json.loads(Path(cached_directory_path, "dataset_info.json").read_text(encoding="utf-8"))["config_name"]
|
| 53 |
+
== Path(cached_directory_path).parts[-3] # no extra params => config_id == config_name
|
| 54 |
+
)
|
| 55 |
+
]
|
| 56 |
+
if not cached_directory_paths:
|
| 57 |
+
cached_directory_paths = [
|
| 58 |
+
cached_directory_path
|
| 59 |
+
for cached_directory_path in glob.glob(os.path.join(cached_datasets_directory_path_root, "*", "*", "*"))
|
| 60 |
+
if os.path.isdir(cached_directory_path)
|
| 61 |
+
]
|
| 62 |
+
available_configs = sorted(
|
| 63 |
+
{Path(cached_directory_path).parts[-3] for cached_directory_path in cached_directory_paths}
|
| 64 |
+
)
|
| 65 |
+
raise ValueError(
|
| 66 |
+
f"Couldn't find cache for {dataset_name}"
|
| 67 |
+
+ (f" for config '{config_id}'" if config_id else "")
|
| 68 |
+
+ (f"\nAvailable configs in the cache: {available_configs}" if available_configs else "")
|
| 69 |
+
)
|
| 70 |
+
# get most recent
|
| 71 |
+
cached_directory_path = Path(sorted(cached_directory_paths, key=_get_modification_time)[-1])
|
| 72 |
+
version, hash = cached_directory_path.parts[-2:]
|
| 73 |
+
other_configs = [
|
| 74 |
+
Path(_cached_directory_path).parts[-3]
|
| 75 |
+
for _cached_directory_path in glob.glob(os.path.join(cached_datasets_directory_path_root, "*", version, hash))
|
| 76 |
+
if os.path.isdir(_cached_directory_path)
|
| 77 |
+
and (
|
| 78 |
+
config_kwargs
|
| 79 |
+
or custom_features
|
| 80 |
+
or json.loads(Path(_cached_directory_path, "dataset_info.json").read_text(encoding="utf-8"))["config_name"]
|
| 81 |
+
== Path(_cached_directory_path).parts[-3] # no extra params => config_id == config_name
|
| 82 |
+
)
|
| 83 |
+
]
|
| 84 |
+
if not config_id and len(other_configs) > 1:
|
| 85 |
+
raise ValueError(
|
| 86 |
+
f"There are multiple '{dataset_name}' configurations in the cache: {', '.join(other_configs)}"
|
| 87 |
+
f"\nPlease specify which configuration to reload from the cache, e.g."
|
| 88 |
+
f"\n\tload_dataset('{dataset_name}', '{other_configs[0]}')"
|
| 89 |
+
)
|
| 90 |
+
config_name = cached_directory_path.parts[-3]
|
| 91 |
+
warning_msg = (
|
| 92 |
+
f"Found the latest cached dataset configuration '{config_name}' at {cached_directory_path} "
|
| 93 |
+
f"(last modified on {time.ctime(_get_modification_time(cached_directory_path))})."
|
| 94 |
+
)
|
| 95 |
+
logger.warning(warning_msg)
|
| 96 |
+
return config_name, version, hash
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
class Cache(datasets.ArrowBasedBuilder):
|
| 100 |
+
def __init__(
|
| 101 |
+
self,
|
| 102 |
+
cache_dir: Optional[str] = None,
|
| 103 |
+
dataset_name: Optional[str] = None,
|
| 104 |
+
config_name: Optional[str] = None,
|
| 105 |
+
version: Optional[str] = "0.0.0",
|
| 106 |
+
hash: Optional[str] = None,
|
| 107 |
+
base_path: Optional[str] = None,
|
| 108 |
+
info: Optional[datasets.DatasetInfo] = None,
|
| 109 |
+
features: Optional[datasets.Features] = None,
|
| 110 |
+
token: Optional[Union[bool, str]] = None,
|
| 111 |
+
repo_id: Optional[str] = None,
|
| 112 |
+
data_files: Optional[Union[str, list, dict, datasets.data_files.DataFilesDict]] = None,
|
| 113 |
+
data_dir: Optional[str] = None,
|
| 114 |
+
storage_options: Optional[dict] = None,
|
| 115 |
+
writer_batch_size: Optional[int] = None,
|
| 116 |
+
**config_kwargs,
|
| 117 |
+
):
|
| 118 |
+
if repo_id is None and dataset_name is None:
|
| 119 |
+
raise ValueError("repo_id or dataset_name is required for the Cache dataset builder")
|
| 120 |
+
if data_files is not None:
|
| 121 |
+
config_kwargs["data_files"] = data_files
|
| 122 |
+
if data_dir is not None:
|
| 123 |
+
config_kwargs["data_dir"] = data_dir
|
| 124 |
+
if hash == "auto" and version == "auto":
|
| 125 |
+
config_name, version, hash = _find_hash_in_cache(
|
| 126 |
+
dataset_name=repo_id or dataset_name,
|
| 127 |
+
config_name=config_name,
|
| 128 |
+
cache_dir=cache_dir,
|
| 129 |
+
config_kwargs=config_kwargs,
|
| 130 |
+
custom_features=features,
|
| 131 |
+
)
|
| 132 |
+
elif hash == "auto" or version == "auto":
|
| 133 |
+
raise NotImplementedError("Pass both hash='auto' and version='auto' instead")
|
| 134 |
+
super().__init__(
|
| 135 |
+
cache_dir=cache_dir,
|
| 136 |
+
dataset_name=dataset_name,
|
| 137 |
+
config_name=config_name,
|
| 138 |
+
version=version,
|
| 139 |
+
hash=hash,
|
| 140 |
+
base_path=base_path,
|
| 141 |
+
info=info,
|
| 142 |
+
token=token,
|
| 143 |
+
repo_id=repo_id,
|
| 144 |
+
storage_options=storage_options,
|
| 145 |
+
writer_batch_size=writer_batch_size,
|
| 146 |
+
)
|
| 147 |
+
|
| 148 |
+
def _info(self) -> datasets.DatasetInfo:
|
| 149 |
+
return datasets.DatasetInfo()
|
| 150 |
+
|
| 151 |
+
def download_and_prepare(self, output_dir: Optional[str] = None, *args, **kwargs):
|
| 152 |
+
if not os.path.exists(self.cache_dir):
|
| 153 |
+
raise ValueError(f"Cache directory for {self.dataset_name} doesn't exist at {self.cache_dir}")
|
| 154 |
+
if output_dir is not None and output_dir != self.cache_dir:
|
| 155 |
+
shutil.copytree(self.cache_dir, output_dir)
|
| 156 |
+
|
| 157 |
+
def _split_generators(self, dl_manager):
|
| 158 |
+
# used to stream from cache
|
| 159 |
+
if isinstance(self.info.splits, datasets.SplitDict):
|
| 160 |
+
split_infos: list[datasets.SplitInfo] = list(self.info.splits.values())
|
| 161 |
+
else:
|
| 162 |
+
raise ValueError(f"Missing splits info for {self.dataset_name} in cache directory {self.cache_dir}")
|
| 163 |
+
return [
|
| 164 |
+
datasets.SplitGenerator(
|
| 165 |
+
name=split_info.name,
|
| 166 |
+
gen_kwargs={
|
| 167 |
+
"files": filenames_for_dataset_split(
|
| 168 |
+
self.cache_dir,
|
| 169 |
+
dataset_name=self.dataset_name,
|
| 170 |
+
split=split_info.name,
|
| 171 |
+
filetype_suffix="arrow",
|
| 172 |
+
shard_lengths=split_info.shard_lengths,
|
| 173 |
+
)
|
| 174 |
+
},
|
| 175 |
+
)
|
| 176 |
+
for split_info in split_infos
|
| 177 |
+
]
|
| 178 |
+
|
| 179 |
+
def _generate_shards(self, files):
|
| 180 |
+
yield from files
|
| 181 |
+
|
| 182 |
+
def _generate_tables(self, files):
|
| 183 |
+
# used to stream from cache
|
| 184 |
+
for file_idx, file in enumerate(files):
|
| 185 |
+
with open(file, "rb") as f:
|
| 186 |
+
try:
|
| 187 |
+
for batch_idx, record_batch in enumerate(pa.ipc.open_stream(f)):
|
| 188 |
+
pa_table = pa.Table.from_batches([record_batch])
|
| 189 |
+
# Uncomment for debugging (will print the Arrow table size and elements)
|
| 190 |
+
# logger.warning(f"pa_table: {pa_table} num rows: {pa_table.num_rows}")
|
| 191 |
+
# logger.warning('\n'.join(str(pa_table.slice(i, 1).to_pydict()) for i in range(pa_table.num_rows)))
|
| 192 |
+
yield Key(file_idx, batch_idx), pa_table
|
| 193 |
+
except ValueError as e:
|
| 194 |
+
logger.error(f"Failed to read file '{file}' with error {type(e)}: {e}")
|
| 195 |
+
raise
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/eval/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/eval/eval.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
from itertools import islice
|
| 4 |
+
from typing import Iterable
|
| 5 |
+
|
| 6 |
+
import pyarrow as pa
|
| 7 |
+
|
| 8 |
+
import datasets
|
| 9 |
+
from datasets.builder import Key
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class Eval(datasets.GeneratorBasedBuilder):
|
| 16 |
+
NUM_EXAMPLES_FOR_FEATURES_INFERENCE = 5
|
| 17 |
+
|
| 18 |
+
def _info(self):
|
| 19 |
+
return datasets.DatasetInfo()
|
| 20 |
+
|
| 21 |
+
def _split_generators(self, dl_manager):
|
| 22 |
+
"""We handle string, list and dicts in datafiles"""
|
| 23 |
+
if not self.config.data_files:
|
| 24 |
+
raise ValueError(f"At least one data file must be specified, but got data_files={self.config.data_files}")
|
| 25 |
+
dl_manager.download_config.extract_on_the_fly = True
|
| 26 |
+
base_data_files = dl_manager.download(self.config.data_files)
|
| 27 |
+
extracted_data_files = dl_manager.extract(base_data_files)
|
| 28 |
+
splits = []
|
| 29 |
+
for split_name, logs in extracted_data_files.items():
|
| 30 |
+
logs_files_iterables = [dl_manager.iter_files(log) for log in logs]
|
| 31 |
+
splits.append(
|
| 32 |
+
datasets.SplitGenerator(
|
| 33 |
+
name=split_name,
|
| 34 |
+
gen_kwargs={
|
| 35 |
+
"logs_files_iterables": logs_files_iterables,
|
| 36 |
+
"base_files": base_data_files[split_name],
|
| 37 |
+
},
|
| 38 |
+
)
|
| 39 |
+
)
|
| 40 |
+
if not self.info.features:
|
| 41 |
+
first_examples = list(
|
| 42 |
+
islice(
|
| 43 |
+
self._iter_samples_from_log_files(logs_files_iterables[0]),
|
| 44 |
+
self.NUM_EXAMPLES_FOR_FEATURES_INFERENCE,
|
| 45 |
+
)
|
| 46 |
+
)
|
| 47 |
+
pa_tables = [pa.Table.from_pylist([example]) for example in first_examples]
|
| 48 |
+
inferred_arrow_schema = pa.concat_tables(pa_tables, promote_options="default").schema
|
| 49 |
+
self.info.features = datasets.Features.from_arrow_schema(inferred_arrow_schema)
|
| 50 |
+
|
| 51 |
+
return splits
|
| 52 |
+
|
| 53 |
+
def _sort_samples_key(self, sample_path: str):
|
| 54 |
+
# looks like "{sample_idx}_epoch_{epoch_idx}""
|
| 55 |
+
(sample_idx_str, epoch_idx_str) = os.path.splitext(os.path.basename(sample_path))[0].split("_epoch_")
|
| 56 |
+
return (int(epoch_idx_str), int(sample_idx_str))
|
| 57 |
+
|
| 58 |
+
def _iter_samples_from_log_files(self, log_files: Iterable[str]):
|
| 59 |
+
sample_files = [log_file for log_file in log_files if os.path.basename(os.path.dirname(log_file)) == "samples"]
|
| 60 |
+
sample_files.sort(key=self._sort_samples_key)
|
| 61 |
+
for sample_file in sample_files:
|
| 62 |
+
with open(sample_file) as f:
|
| 63 |
+
sample = json.load(f)
|
| 64 |
+
for field in sample:
|
| 65 |
+
if isinstance(sample[field], dict):
|
| 66 |
+
sample[field] = json.dumps(sample[field])
|
| 67 |
+
if isinstance(sample[field], list):
|
| 68 |
+
sample[field] = [json.dumps(x) for x in sample[field]]
|
| 69 |
+
yield sample
|
| 70 |
+
|
| 71 |
+
def _generate_shards(self, base_files, logs_files_iterables):
|
| 72 |
+
yield from base_files
|
| 73 |
+
|
| 74 |
+
def _generate_examples(self, base_files, logs_files_iterables):
|
| 75 |
+
for file_idx, log_files in enumerate(logs_files_iterables):
|
| 76 |
+
for sample_idx, sample in enumerate(self._iter_samples_from_log_files(log_files)):
|
| 77 |
+
yield Key(file_idx, sample_idx), sample
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/hdf5/hdf5.py
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from dataclasses import dataclass, field
|
| 2 |
+
from typing import TYPE_CHECKING, Optional
|
| 3 |
+
|
| 4 |
+
import numpy as np
|
| 5 |
+
import pyarrow as pa
|
| 6 |
+
|
| 7 |
+
import datasets
|
| 8 |
+
from datasets.builder import Key
|
| 9 |
+
from datasets.features.features import (
|
| 10 |
+
Array2D,
|
| 11 |
+
Array3D,
|
| 12 |
+
Array4D,
|
| 13 |
+
Array5D,
|
| 14 |
+
Features,
|
| 15 |
+
LargeList,
|
| 16 |
+
List,
|
| 17 |
+
Value,
|
| 18 |
+
_ArrayXD,
|
| 19 |
+
_arrow_to_datasets_dtype,
|
| 20 |
+
)
|
| 21 |
+
from datasets.table import cast_table_to_features
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
if TYPE_CHECKING:
|
| 25 |
+
import h5py
|
| 26 |
+
|
| 27 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 28 |
+
|
| 29 |
+
EXTENSIONS = [".h5", ".hdf5"]
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
@dataclass
|
| 33 |
+
class HDF5Config(datasets.BuilderConfig):
|
| 34 |
+
"""BuilderConfig for HDF5."""
|
| 35 |
+
|
| 36 |
+
batch_size: Optional[int] = None
|
| 37 |
+
features: Optional[datasets.Features] = None
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
class HDF5(datasets.ArrowBasedBuilder):
|
| 41 |
+
"""ArrowBasedBuilder that converts HDF5 files to Arrow tables using the HF extension types."""
|
| 42 |
+
|
| 43 |
+
BUILDER_CONFIG_CLASS = HDF5Config
|
| 44 |
+
|
| 45 |
+
def _info(self):
|
| 46 |
+
return datasets.DatasetInfo(features=self.config.features)
|
| 47 |
+
|
| 48 |
+
def _split_generators(self, dl_manager):
|
| 49 |
+
import h5py
|
| 50 |
+
|
| 51 |
+
if not self.config.data_files:
|
| 52 |
+
raise ValueError(f"At least one data file must be specified, but got data_files={self.config.data_files}")
|
| 53 |
+
data_files = dl_manager.download(self.config.data_files)
|
| 54 |
+
splits = []
|
| 55 |
+
for split_name, files in data_files.items():
|
| 56 |
+
# Infer features from first file
|
| 57 |
+
if self.info.features is None:
|
| 58 |
+
for first_file in files:
|
| 59 |
+
with open(first_file, "rb") as f:
|
| 60 |
+
with h5py.File(f, "r") as h5:
|
| 61 |
+
self.info.features = _recursive_infer_features(h5)
|
| 62 |
+
break
|
| 63 |
+
splits.append(datasets.SplitGenerator(name=split_name, gen_kwargs={"files": files}))
|
| 64 |
+
return splits
|
| 65 |
+
|
| 66 |
+
def _generate_shards(self, files):
|
| 67 |
+
yield from files
|
| 68 |
+
|
| 69 |
+
def _generate_tables(self, files):
|
| 70 |
+
import h5py
|
| 71 |
+
|
| 72 |
+
batch_size_cfg = self.config.batch_size
|
| 73 |
+
for file_idx, file in enumerate(files):
|
| 74 |
+
try:
|
| 75 |
+
with open(file, "rb") as f:
|
| 76 |
+
with h5py.File(f, "r") as h5:
|
| 77 |
+
# Infer features and lengths from first file
|
| 78 |
+
if self.info.features is None:
|
| 79 |
+
self.info.features = _recursive_infer_features(h5)
|
| 80 |
+
num_rows = _check_dataset_lengths(h5, self.info.features)
|
| 81 |
+
if num_rows is None:
|
| 82 |
+
logger.warning(f"File {file} contains no data, skipping...")
|
| 83 |
+
continue
|
| 84 |
+
effective_batch = batch_size_cfg or self._writer_batch_size or num_rows
|
| 85 |
+
for batch_idx, start in enumerate(range(0, num_rows, effective_batch)):
|
| 86 |
+
end = min(start + effective_batch, num_rows)
|
| 87 |
+
pa_table = _recursive_load_arrays(h5, self.info.features, start, end)
|
| 88 |
+
if pa_table is None:
|
| 89 |
+
logger.warning(f"File {file} contains no data, skipping...")
|
| 90 |
+
continue
|
| 91 |
+
yield Key(file_idx, batch_idx), cast_table_to_features(pa_table, self.info.features)
|
| 92 |
+
except ValueError as e:
|
| 93 |
+
logger.error(f"Failed to read file '{file}' with error {type(e)}: {e}")
|
| 94 |
+
raise
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
# ┌───────────┐
|
| 98 |
+
# │ Complex │
|
| 99 |
+
# └───────────┘
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def _is_complex_dtype(dtype: np.dtype) -> bool:
|
| 103 |
+
if dtype.kind == "c":
|
| 104 |
+
return True
|
| 105 |
+
if dtype.subdtype is not None:
|
| 106 |
+
return _is_complex_dtype(dtype.subdtype[0])
|
| 107 |
+
return False
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
def _create_complex_features(dset) -> Features:
|
| 111 |
+
if dset.dtype.subdtype is not None:
|
| 112 |
+
dtype, data_shape = dset.dtype.subdtype
|
| 113 |
+
else:
|
| 114 |
+
data_shape = dset.shape[1:]
|
| 115 |
+
dtype = dset.dtype
|
| 116 |
+
|
| 117 |
+
if dtype == np.complex64:
|
| 118 |
+
# two float32s
|
| 119 |
+
value_type = Value("float32")
|
| 120 |
+
elif dtype == np.complex128:
|
| 121 |
+
# two float64s
|
| 122 |
+
value_type = Value("float64")
|
| 123 |
+
else:
|
| 124 |
+
logger.warning(f"Found complex dtype {dtype} that is not supported. Converting to float64...")
|
| 125 |
+
value_type = Value("float64")
|
| 126 |
+
|
| 127 |
+
return Features(
|
| 128 |
+
{
|
| 129 |
+
"real": _create_sized_feature_impl(data_shape, value_type),
|
| 130 |
+
"imag": _create_sized_feature_impl(data_shape, value_type),
|
| 131 |
+
}
|
| 132 |
+
)
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
def _convert_complex_to_nested(arr: np.ndarray) -> pa.StructArray:
|
| 136 |
+
data = {
|
| 137 |
+
"real": datasets.features.features.numpy_to_pyarrow_listarray(arr.real),
|
| 138 |
+
"imag": datasets.features.features.numpy_to_pyarrow_listarray(arr.imag),
|
| 139 |
+
}
|
| 140 |
+
return pa.StructArray.from_arrays([data["real"], data["imag"]], names=["real", "imag"])
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
# ┌────────────┐
|
| 144 |
+
# │ Compound │
|
| 145 |
+
# └────────────┘
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
def _is_compound_dtype(dtype: np.dtype) -> bool:
|
| 149 |
+
return dtype.kind == "V"
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
@dataclass
|
| 153 |
+
class _CompoundGroup:
|
| 154 |
+
dset: "h5py.Dataset"
|
| 155 |
+
data: np.ndarray = None
|
| 156 |
+
|
| 157 |
+
def items(self):
|
| 158 |
+
for field_name in self.dset.dtype.names:
|
| 159 |
+
field_dtype = self.dset.dtype[field_name]
|
| 160 |
+
yield field_name, _CompoundField(self.data, field_name, field_dtype)
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
@dataclass
|
| 164 |
+
class _CompoundField:
|
| 165 |
+
data: Optional[np.ndarray]
|
| 166 |
+
name: str
|
| 167 |
+
dtype: np.dtype
|
| 168 |
+
shape: tuple[int, ...] = field(init=False)
|
| 169 |
+
|
| 170 |
+
def __post_init__(self):
|
| 171 |
+
self.shape = (len(self.data) if self.data is not None else 0,) + self.dtype.shape
|
| 172 |
+
|
| 173 |
+
def __getitem__(self, key):
|
| 174 |
+
return self.data[key][self.name]
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
def _create_compound_features(dset) -> Features:
|
| 178 |
+
mock_group = _CompoundGroup(dset)
|
| 179 |
+
return _recursive_infer_features(mock_group)
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
def _convert_compound_to_nested(arr, dset) -> pa.StructArray:
|
| 183 |
+
mock_group = _CompoundGroup(dset, data=arr)
|
| 184 |
+
features = _create_compound_features(dset)
|
| 185 |
+
return _recursive_load_arrays(mock_group, features, 0, len(arr))
|
| 186 |
+
|
| 187 |
+
|
| 188 |
+
# ┌───────────────────┐
|
| 189 |
+
# │ Variable-Length │
|
| 190 |
+
# └───────────────────┘
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
def _is_vlen_dtype(dtype: np.dtype) -> bool:
|
| 194 |
+
if dtype.metadata and "vlen" in dtype.metadata:
|
| 195 |
+
return True
|
| 196 |
+
return False
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
def _create_vlen_features(dset) -> Features:
|
| 200 |
+
vlen_dtype = dset.dtype.metadata["vlen"]
|
| 201 |
+
if vlen_dtype in (str, bytes):
|
| 202 |
+
return Value("string")
|
| 203 |
+
inner_feature = _np_to_pa_to_hf_value(vlen_dtype)
|
| 204 |
+
return List(inner_feature)
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
def _convert_vlen_to_array(arr: np.ndarray) -> pa.Array:
|
| 208 |
+
return datasets.features.features.numpy_to_pyarrow_listarray(arr)
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
# ┌───────────┐
|
| 212 |
+
# │ Generic │
|
| 213 |
+
# └───────────┘
|
| 214 |
+
|
| 215 |
+
|
| 216 |
+
def _recursive_infer_features(h5_obj) -> Features:
|
| 217 |
+
features_dict = {}
|
| 218 |
+
for path, dset in h5_obj.items():
|
| 219 |
+
if _is_group(dset):
|
| 220 |
+
features = _recursive_infer_features(dset)
|
| 221 |
+
if features:
|
| 222 |
+
features_dict[path] = features
|
| 223 |
+
elif _is_dataset(dset):
|
| 224 |
+
features = _infer_feature(dset)
|
| 225 |
+
if features:
|
| 226 |
+
features_dict[path] = features
|
| 227 |
+
|
| 228 |
+
return Features(features_dict)
|
| 229 |
+
|
| 230 |
+
|
| 231 |
+
def _infer_feature(dset):
|
| 232 |
+
if _is_complex_dtype(dset.dtype):
|
| 233 |
+
return _create_complex_features(dset)
|
| 234 |
+
elif _is_compound_dtype(dset.dtype) or dset.dtype.kind == "V":
|
| 235 |
+
return _create_compound_features(dset)
|
| 236 |
+
elif _is_vlen_dtype(dset.dtype):
|
| 237 |
+
return _create_vlen_features(dset)
|
| 238 |
+
return _create_sized_feature(dset)
|
| 239 |
+
|
| 240 |
+
|
| 241 |
+
def _load_array(dset, path: str, start: int, end: int) -> pa.Array:
|
| 242 |
+
arr = dset[start:end]
|
| 243 |
+
|
| 244 |
+
if _is_vlen_dtype(dset.dtype):
|
| 245 |
+
return _convert_vlen_to_array(arr)
|
| 246 |
+
elif _is_complex_dtype(dset.dtype):
|
| 247 |
+
return _convert_complex_to_nested(arr)
|
| 248 |
+
elif _is_compound_dtype(dset.dtype):
|
| 249 |
+
return _convert_compound_to_nested(arr, dset)
|
| 250 |
+
elif dset.dtype.kind == "O":
|
| 251 |
+
raise ValueError(
|
| 252 |
+
f"Object dtype dataset '{path}' is not supported. "
|
| 253 |
+
f"For variable-length data, please use h5py.vlen_dtype() "
|
| 254 |
+
f"when creating the HDF5 file. "
|
| 255 |
+
f"See: https://docs.h5py.org/en/stable/special.html#variable-length-strings"
|
| 256 |
+
)
|
| 257 |
+
else:
|
| 258 |
+
# If any non-batch dimension is zero, emit an unsized pa.list_
|
| 259 |
+
# to avoid creating FixedSizeListArray with list_size=0.
|
| 260 |
+
if any(dim == 0 for dim in dset.shape[1:]):
|
| 261 |
+
inner_type = pa.from_numpy_dtype(dset.dtype)
|
| 262 |
+
return pa.array([[] for _ in arr], type=pa.list_(inner_type))
|
| 263 |
+
else:
|
| 264 |
+
return datasets.features.features.numpy_to_pyarrow_listarray(arr)
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
def _recursive_load_arrays(h5_obj, features: Features, start: int, end: int):
|
| 268 |
+
batch_dict = {}
|
| 269 |
+
for path, dset in h5_obj.items():
|
| 270 |
+
if path not in features:
|
| 271 |
+
continue
|
| 272 |
+
if _is_group(dset):
|
| 273 |
+
arr = _recursive_load_arrays(dset, features[path], start, end)
|
| 274 |
+
elif _is_dataset(dset):
|
| 275 |
+
arr = _load_array(dset, path, start, end)
|
| 276 |
+
else:
|
| 277 |
+
raise ValueError(f"Unexpected type {type(dset)}")
|
| 278 |
+
|
| 279 |
+
if arr is not None:
|
| 280 |
+
batch_dict[path] = arr
|
| 281 |
+
|
| 282 |
+
if _is_file(h5_obj):
|
| 283 |
+
return pa.Table.from_pydict(batch_dict)
|
| 284 |
+
|
| 285 |
+
if batch_dict:
|
| 286 |
+
should_chunk, keys, values = False, [], []
|
| 287 |
+
for k, v in batch_dict.items():
|
| 288 |
+
if isinstance(v, pa.ChunkedArray):
|
| 289 |
+
should_chunk = True
|
| 290 |
+
v = v.combine_chunks()
|
| 291 |
+
keys.append(k)
|
| 292 |
+
values.append(v)
|
| 293 |
+
|
| 294 |
+
sarr = pa.StructArray.from_arrays(values, names=keys)
|
| 295 |
+
return pa.chunked_array(sarr) if should_chunk else sarr
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
# ┌─────────────┐
|
| 299 |
+
# │ Utilities │
|
| 300 |
+
# └─────────────┘
|
| 301 |
+
|
| 302 |
+
|
| 303 |
+
def _create_sized_feature(dset):
|
| 304 |
+
dset_shape = dset.shape[1:]
|
| 305 |
+
value_feature = _np_to_pa_to_hf_value(dset.dtype)
|
| 306 |
+
return _create_sized_feature_impl(dset_shape, value_feature)
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
def _create_sized_feature_impl(dset_shape, value_feature):
|
| 310 |
+
dtype_str = value_feature.dtype
|
| 311 |
+
if any(dim == 0 for dim in dset_shape):
|
| 312 |
+
logger.warning(
|
| 313 |
+
f"HDF5 to Arrow: Found a dataset with shape {dset_shape} and dtype {dtype_str} that has a dimension with size 0. Shape information will be lost in the conversion to List({value_feature})."
|
| 314 |
+
)
|
| 315 |
+
return List(value_feature)
|
| 316 |
+
|
| 317 |
+
rank = len(dset_shape)
|
| 318 |
+
if rank == 0:
|
| 319 |
+
return value_feature
|
| 320 |
+
elif rank == 1:
|
| 321 |
+
return List(value_feature, length=dset_shape[0])
|
| 322 |
+
elif rank <= 5:
|
| 323 |
+
return _sized_arrayxd(rank)(shape=dset_shape, dtype=dtype_str)
|
| 324 |
+
else:
|
| 325 |
+
raise TypeError(f"Array{rank}D not supported. Maximum 5 dimensions allowed.")
|
| 326 |
+
|
| 327 |
+
|
| 328 |
+
def _sized_arrayxd(rank: int):
|
| 329 |
+
return {2: Array2D, 3: Array3D, 4: Array4D, 5: Array5D}[rank]
|
| 330 |
+
|
| 331 |
+
|
| 332 |
+
def _np_to_pa_to_hf_value(numpy_dtype: np.dtype) -> Value:
|
| 333 |
+
return Value(dtype=_arrow_to_datasets_dtype(pa.from_numpy_dtype(numpy_dtype)))
|
| 334 |
+
|
| 335 |
+
|
| 336 |
+
def _first_dataset(h5_obj, features: Features, prefix=""):
|
| 337 |
+
for path, dset in h5_obj.items():
|
| 338 |
+
if path not in features:
|
| 339 |
+
continue
|
| 340 |
+
if _is_group(dset):
|
| 341 |
+
found = _first_dataset(dset, features[path], prefix=f"{prefix}{path}/")
|
| 342 |
+
if found is not None:
|
| 343 |
+
return found
|
| 344 |
+
elif _is_dataset(dset):
|
| 345 |
+
return f"{prefix}{path}"
|
| 346 |
+
|
| 347 |
+
|
| 348 |
+
def _check_dataset_lengths(h5_obj, features: Features) -> int:
|
| 349 |
+
first_path = _first_dataset(h5_obj, features)
|
| 350 |
+
if first_path is None:
|
| 351 |
+
return None
|
| 352 |
+
|
| 353 |
+
num_rows = h5_obj[first_path].shape[0]
|
| 354 |
+
for path, dset in h5_obj.items():
|
| 355 |
+
if path not in features:
|
| 356 |
+
continue
|
| 357 |
+
if _is_dataset(dset):
|
| 358 |
+
if dset.shape[0] != num_rows:
|
| 359 |
+
raise ValueError(f"Dataset '{path}' has length {dset.shape[0]} but expected {num_rows}")
|
| 360 |
+
return num_rows
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
def _is_group(h5_obj) -> bool:
|
| 364 |
+
import h5py
|
| 365 |
+
|
| 366 |
+
return isinstance(h5_obj, h5py.Group) or isinstance(h5_obj, _CompoundGroup)
|
| 367 |
+
|
| 368 |
+
|
| 369 |
+
def _is_dataset(h5_obj) -> bool:
|
| 370 |
+
import h5py
|
| 371 |
+
|
| 372 |
+
return isinstance(h5_obj, h5py.Dataset) or isinstance(h5_obj, _CompoundField)
|
| 373 |
+
|
| 374 |
+
|
| 375 |
+
def _is_file(h5_obj) -> bool:
|
| 376 |
+
import h5py
|
| 377 |
+
|
| 378 |
+
return isinstance(h5_obj, h5py.File)
|
| 379 |
+
|
| 380 |
+
|
| 381 |
+
def _has_zero_dimensions(feature):
|
| 382 |
+
if isinstance(feature, _ArrayXD):
|
| 383 |
+
return any(dim == 0 for dim in feature.shape)
|
| 384 |
+
elif isinstance(feature, List):
|
| 385 |
+
return feature.length == 0 or _has_zero_dimensions(feature.feature)
|
| 386 |
+
elif isinstance(feature, LargeList):
|
| 387 |
+
return _has_zero_dimensions(feature.feature)
|
| 388 |
+
else:
|
| 389 |
+
return False
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/json/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/json/json.py
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import os
|
| 3 |
+
from dataclasses import dataclass
|
| 4 |
+
from typing import Literal, Optional
|
| 5 |
+
|
| 6 |
+
import pandas as pd
|
| 7 |
+
import pyarrow as pa
|
| 8 |
+
import pyarrow.json as paj
|
| 9 |
+
|
| 10 |
+
import datasets
|
| 11 |
+
import datasets.config
|
| 12 |
+
from datasets.builder import Key
|
| 13 |
+
from datasets.table import table_cast
|
| 14 |
+
from datasets.utils.file_utils import readline
|
| 15 |
+
from datasets.utils.json import (
|
| 16 |
+
find_mixed_struct_types_field_paths,
|
| 17 |
+
get_json_field_path_from_pyarrow_json_error,
|
| 18 |
+
get_json_field_paths_from_feature,
|
| 19 |
+
insert_json_field_path,
|
| 20 |
+
json_encode_field,
|
| 21 |
+
json_encode_fields_in_json_lines,
|
| 22 |
+
set_json_types_in_feature,
|
| 23 |
+
ujson_dumps,
|
| 24 |
+
ujson_loads,
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def pandas_read_json(path_or_buf, **kwargs):
|
| 32 |
+
if datasets.config.PANDAS_VERSION.major >= 2:
|
| 33 |
+
kwargs["dtype_backend"] = "pyarrow"
|
| 34 |
+
return pd.read_json(path_or_buf, **kwargs)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class FullReadDisallowed(Exception):
|
| 38 |
+
pass
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
@dataclass
|
| 42 |
+
class JsonConfig(datasets.BuilderConfig):
|
| 43 |
+
"""BuilderConfig for JSON."""
|
| 44 |
+
|
| 45 |
+
features: Optional[datasets.Features] = None
|
| 46 |
+
encoding: str = "utf-8"
|
| 47 |
+
encoding_errors: Optional[str] = None
|
| 48 |
+
field: Optional[str] = None
|
| 49 |
+
use_threads: bool = True # deprecated
|
| 50 |
+
block_size: Optional[int] = None # deprecated
|
| 51 |
+
chunksize: int = 10 << 20 # 10MB
|
| 52 |
+
newlines_in_values: Optional[bool] = None
|
| 53 |
+
on_mixed_types: Optional[Literal["use_json"]] = "use_json"
|
| 54 |
+
parse_agent_traces: bool = True
|
| 55 |
+
|
| 56 |
+
def __post_init__(self):
|
| 57 |
+
super().__post_init__()
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
class Json(datasets.ArrowBasedBuilder):
|
| 61 |
+
BUILDER_CONFIG_CLASS = JsonConfig
|
| 62 |
+
|
| 63 |
+
def _info(self):
|
| 64 |
+
if self.config.block_size is not None:
|
| 65 |
+
logger.warning("The JSON loader parameter `block_size` is deprecated. Please use `chunksize` instead")
|
| 66 |
+
self.config.chunksize = self.config.block_size
|
| 67 |
+
if self.config.use_threads is not True:
|
| 68 |
+
logger.warning(
|
| 69 |
+
"The JSON loader parameter `use_threads` is deprecated and doesn't have any effect anymore."
|
| 70 |
+
)
|
| 71 |
+
if self.config.newlines_in_values is not None:
|
| 72 |
+
raise ValueError("The JSON loader parameter `newlines_in_values` is no longer supported")
|
| 73 |
+
return datasets.DatasetInfo(features=self.config.features)
|
| 74 |
+
|
| 75 |
+
def _split_generators(self, dl_manager):
|
| 76 |
+
"""We handle string, list and dicts in datafiles"""
|
| 77 |
+
if not self.config.data_files:
|
| 78 |
+
raise ValueError(f"At least one data file must be specified, but got data_files={self.config.data_files}")
|
| 79 |
+
dl_manager.download_config.extract_on_the_fly = True
|
| 80 |
+
base_data_files = dl_manager.download(self.config.data_files)
|
| 81 |
+
extracted_data_files = dl_manager.extract(base_data_files)
|
| 82 |
+
splits = []
|
| 83 |
+
for split_name, extracted_files in extracted_data_files.items():
|
| 84 |
+
files_iterables = [dl_manager.iter_files(extracted_file) for extracted_file in extracted_files]
|
| 85 |
+
splits.append(
|
| 86 |
+
datasets.SplitGenerator(
|
| 87 |
+
name=split_name,
|
| 88 |
+
gen_kwargs={
|
| 89 |
+
"files_iterables": files_iterables,
|
| 90 |
+
"base_files": base_data_files[split_name],
|
| 91 |
+
"original_files": self.config.data_files[split_name],
|
| 92 |
+
},
|
| 93 |
+
)
|
| 94 |
+
)
|
| 95 |
+
if self.info.features is None:
|
| 96 |
+
try:
|
| 97 |
+
pa_table = next(iter(self._generate_tables(**splits[0].gen_kwargs, allow_full_read=False)))[1]
|
| 98 |
+
self.info.features = datasets.Features.from_arrow_schema(pa_table.schema)
|
| 99 |
+
if self.config.parse_agent_traces and has_agent_traces_markers(self.info.features):
|
| 100 |
+
self.info.features = AGENT_TRACES_FEATURES
|
| 101 |
+
except FullReadDisallowed:
|
| 102 |
+
pass
|
| 103 |
+
return splits
|
| 104 |
+
|
| 105 |
+
def _cast_table(self, pa_table: pa.Table, json_field_paths=()) -> pa.Table:
|
| 106 |
+
if self.info.features is not None:
|
| 107 |
+
# adding missing columns
|
| 108 |
+
for column_name in set(self.info.features) - set(pa_table.column_names):
|
| 109 |
+
type = self.info.features.arrow_schema.field(column_name).type
|
| 110 |
+
pa_table = pa_table.append_column(column_name, pa.array([None] * len(pa_table), type=type))
|
| 111 |
+
# convert to string when needed
|
| 112 |
+
for i, column_name in enumerate(pa_table.column_names):
|
| 113 |
+
if pa.types.is_struct(pa_table[column_name].type) and self.info.features.get(
|
| 114 |
+
column_name, None
|
| 115 |
+
) == datasets.Value("string"):
|
| 116 |
+
jsonl = (
|
| 117 |
+
pa_table[column_name]
|
| 118 |
+
.to_pandas(types_mapper=pd.ArrowDtype)
|
| 119 |
+
.to_json(orient="records", lines=True)
|
| 120 |
+
)
|
| 121 |
+
string_array = pa.array(
|
| 122 |
+
(None if x.strip() == "null" else x.strip() for x in jsonl.split("\n") if x.strip()),
|
| 123 |
+
type=pa.string(),
|
| 124 |
+
)
|
| 125 |
+
pa_table = pa_table.set_column(i, column_name, string_array)
|
| 126 |
+
# more expensive cast to support nested structures with keys in a different order
|
| 127 |
+
# allows str <-> int/float or str to Audio for example
|
| 128 |
+
pa_table = table_cast(pa_table, self.info.features.arrow_schema)
|
| 129 |
+
elif json_field_paths:
|
| 130 |
+
features = datasets.Features.from_arrow_schema(pa_table.schema)
|
| 131 |
+
features = set_json_types_in_feature(features, json_field_paths)
|
| 132 |
+
pa_table = table_cast(pa_table, features.arrow_schema)
|
| 133 |
+
return pa_table
|
| 134 |
+
|
| 135 |
+
def _generate_shards(self, base_files, files_iterables, original_files):
|
| 136 |
+
yield from base_files
|
| 137 |
+
|
| 138 |
+
def _generate_tables(self, base_files, files_iterables, original_files, allow_full_read=True):
|
| 139 |
+
json_field_paths = []
|
| 140 |
+
is_agent_traces = False
|
| 141 |
+
|
| 142 |
+
if self.info.features is not None:
|
| 143 |
+
if self.info.features == AGENT_TRACES_FEATURES:
|
| 144 |
+
is_agent_traces = True
|
| 145 |
+
else:
|
| 146 |
+
json_field_paths = get_json_field_paths_from_feature(self.info.features)
|
| 147 |
+
|
| 148 |
+
for shard_idx, files_iterable in enumerate(files_iterables):
|
| 149 |
+
for file in files_iterable:
|
| 150 |
+
# If the file is one json object and if we need to look at the items in one specific field
|
| 151 |
+
if self.config.field is not None:
|
| 152 |
+
if not allow_full_read:
|
| 153 |
+
raise FullReadDisallowed()
|
| 154 |
+
with open(file, encoding=self.config.encoding, errors=self.config.encoding_errors) as f:
|
| 155 |
+
dataset = ujson_loads(f.read())
|
| 156 |
+
# We keep only the field we are interested in
|
| 157 |
+
dataset = dataset[self.config.field]
|
| 158 |
+
df = pandas_read_json(io.StringIO(ujson_dumps(dataset)))
|
| 159 |
+
if df.columns.tolist() == [0]:
|
| 160 |
+
df.columns = list(self.config.features) if self.config.features else ["text"]
|
| 161 |
+
pa_table = pa.Table.from_pandas(df, preserve_index=False)
|
| 162 |
+
yield Key(shard_idx, 0), self._cast_table(pa_table)
|
| 163 |
+
|
| 164 |
+
# If the files are agent traces (one row = one file)
|
| 165 |
+
elif is_agent_traces:
|
| 166 |
+
with open(file, "r", encoding="utf-8") as f:
|
| 167 |
+
traces = f.readlines()
|
| 168 |
+
harness, session_id = parse_traces_info(traces)
|
| 169 |
+
file_path = original_files[shard_idx]
|
| 170 |
+
if file_path.startswith(self.base_path):
|
| 171 |
+
file_path = os.path.relpath(file_path, self.base_path)
|
| 172 |
+
pa_table = pa.Table.from_pydict(
|
| 173 |
+
{
|
| 174 |
+
"harness": [harness],
|
| 175 |
+
"session_id": [session_id],
|
| 176 |
+
"traces": [traces],
|
| 177 |
+
"file_path": [file_path],
|
| 178 |
+
}
|
| 179 |
+
)
|
| 180 |
+
yield Key(shard_idx, 0), self._cast_table(pa_table)
|
| 181 |
+
|
| 182 |
+
# If the file has one json object per line
|
| 183 |
+
else:
|
| 184 |
+
with open(file, "rb") as f:
|
| 185 |
+
batch_idx = 0
|
| 186 |
+
# Use block_size equal to the chunk size divided by 32 to leverage multithreading
|
| 187 |
+
# Set a default minimum value of 16kB if the chunk size is really small
|
| 188 |
+
block_size = max(self.config.chunksize // 32, 16 << 10)
|
| 189 |
+
encoding_errors = (
|
| 190 |
+
self.config.encoding_errors if self.config.encoding_errors is not None else "strict"
|
| 191 |
+
)
|
| 192 |
+
while True:
|
| 193 |
+
batch = f.read(self.config.chunksize)
|
| 194 |
+
if not batch:
|
| 195 |
+
break
|
| 196 |
+
if batch.startswith(b"["):
|
| 197 |
+
if not allow_full_read:
|
| 198 |
+
raise FullReadDisallowed()
|
| 199 |
+
else:
|
| 200 |
+
# convert to JSON Lines
|
| 201 |
+
full_data = batch + f.read()
|
| 202 |
+
if b"{" in batch[:100].split(b'"', 1)[0]: # list of objects
|
| 203 |
+
batch = "\n".join(ujson_dumps(x) for x in ujson_loads(full_data)).encode()
|
| 204 |
+
else: # list of strings
|
| 205 |
+
batch = "\n".join(
|
| 206 |
+
ujson_dumps({"text": x}) for x in ujson_loads(full_data)
|
| 207 |
+
).encode()
|
| 208 |
+
# Finish current line
|
| 209 |
+
try:
|
| 210 |
+
batch += f.readline()
|
| 211 |
+
except (AttributeError, io.UnsupportedOperation):
|
| 212 |
+
batch += readline(f)
|
| 213 |
+
# PyArrow only accepts utf-8 encoded bytes
|
| 214 |
+
if self.config.encoding != "utf-8":
|
| 215 |
+
batch = batch.decode(self.config.encoding, errors=encoding_errors).encode("utf-8")
|
| 216 |
+
# On first batch we check for lists of objects with arbitrary fields
|
| 217 |
+
if (
|
| 218 |
+
shard_idx == 0
|
| 219 |
+
and batch_idx == 0
|
| 220 |
+
and self.info.features is None
|
| 221 |
+
and self.config.on_mixed_types == "use_json"
|
| 222 |
+
):
|
| 223 |
+
try:
|
| 224 |
+
examples = [ujson_loads(line) for line in batch.splitlines()]
|
| 225 |
+
except ValueError:
|
| 226 |
+
# the file is likely not JSON Lines and may contain one single multi-line JSON object
|
| 227 |
+
pass
|
| 228 |
+
else:
|
| 229 |
+
json_field_paths += find_mixed_struct_types_field_paths(examples)
|
| 230 |
+
# Re-encode JSON fields
|
| 231 |
+
original_batch = batch
|
| 232 |
+
if json_field_paths:
|
| 233 |
+
examples = [ujson_loads(line) for line in batch.splitlines()]
|
| 234 |
+
for json_field_path in json_field_paths:
|
| 235 |
+
examples = [json_encode_field(examples, json_field_path) for examples in examples]
|
| 236 |
+
batch = "\n".join(ujson_dumps(example) for example in examples).encode()
|
| 237 |
+
# Disable parallelism if block size is ~ len(batch) to avoid segfault
|
| 238 |
+
block_size = len(batch) if len(batch) // 8 > block_size else block_size
|
| 239 |
+
try:
|
| 240 |
+
while True:
|
| 241 |
+
try:
|
| 242 |
+
pa_table = paj.read_json(
|
| 243 |
+
io.BytesIO(batch), read_options=paj.ReadOptions(block_size=block_size)
|
| 244 |
+
)
|
| 245 |
+
break
|
| 246 |
+
except (pa.ArrowInvalid, pa.ArrowNotImplementedError) as e:
|
| 247 |
+
if batch.startswith(b"["): # paj.read_json only supports json lines
|
| 248 |
+
raise
|
| 249 |
+
elif self.config.on_mixed_types == "use_json" and (
|
| 250 |
+
isinstance(e, pa.ArrowInvalid)
|
| 251 |
+
and "JSON parse error: Column(" in str(e)
|
| 252 |
+
and ") changed from" in str(e)
|
| 253 |
+
):
|
| 254 |
+
json_field_path = get_json_field_path_from_pyarrow_json_error(str(e))
|
| 255 |
+
insert_json_field_path(json_field_paths, json_field_path)
|
| 256 |
+
batch = json_encode_fields_in_json_lines(original_batch, json_field_paths)
|
| 257 |
+
elif (
|
| 258 |
+
"straddling" in str(e) or "JSON conversion to" in str(e)
|
| 259 |
+
) and block_size < len(batch):
|
| 260 |
+
# Increase the block size in case it was too small.
|
| 261 |
+
# The block size will be reset for the next file.
|
| 262 |
+
# this is needed in case of "stradding" or for some JSON conversions (see https://github.com/huggingface/datasets/issues/2799)
|
| 263 |
+
logger.debug(
|
| 264 |
+
f"Batch of {len(batch)} bytes couldn't be parsed with block_size={block_size}. Retrying with block_size={block_size * 2}."
|
| 265 |
+
)
|
| 266 |
+
block_size *= 2
|
| 267 |
+
else:
|
| 268 |
+
raise
|
| 269 |
+
except pa.ArrowInvalid as e:
|
| 270 |
+
if not allow_full_read:
|
| 271 |
+
raise FullReadDisallowed()
|
| 272 |
+
try:
|
| 273 |
+
with open(
|
| 274 |
+
file, encoding=self.config.encoding, errors=self.config.encoding_errors
|
| 275 |
+
) as f:
|
| 276 |
+
df = pandas_read_json(f)
|
| 277 |
+
except ValueError:
|
| 278 |
+
logger.error(f"Failed to load JSON from file '{file}' with error {type(e)}: {e}")
|
| 279 |
+
raise e
|
| 280 |
+
if df.columns.tolist() == [0]:
|
| 281 |
+
df.columns = list(self.config.features) if self.config.features else ["text"]
|
| 282 |
+
try:
|
| 283 |
+
pa_table = pa.Table.from_pandas(df, preserve_index=False)
|
| 284 |
+
except pa.ArrowInvalid as e:
|
| 285 |
+
logger.error(
|
| 286 |
+
f"Failed to convert pandas DataFrame to Arrow Table from file '{file}' with error {type(e)}: {e}"
|
| 287 |
+
)
|
| 288 |
+
raise ValueError(
|
| 289 |
+
f"Failed to convert pandas DataFrame to Arrow Table from file {file}."
|
| 290 |
+
) from None
|
| 291 |
+
yield Key(shard_idx, 0), self._cast_table(pa_table)
|
| 292 |
+
break
|
| 293 |
+
yield (
|
| 294 |
+
Key(shard_idx, batch_idx),
|
| 295 |
+
self._cast_table(pa_table, json_field_paths=json_field_paths),
|
| 296 |
+
)
|
| 297 |
+
batch_idx += 1
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
AGENT_TRACES_TYPES_VALUES = {
|
| 301 |
+
"claude_code": ["user", "assistant", "system"],
|
| 302 |
+
"pi": ["session", "message"],
|
| 303 |
+
"codex": ["session_meta", "turn_context", "response_item", "event_msg"],
|
| 304 |
+
}
|
| 305 |
+
AGENT_TRACES_TYPE_TO_HARNESS = {}
|
| 306 |
+
for _harness, _trace_types in AGENT_TRACES_TYPES_VALUES.items():
|
| 307 |
+
for _trace_type in _trace_types:
|
| 308 |
+
AGENT_TRACES_TYPE_TO_HARNESS[_trace_type] = _harness
|
| 309 |
+
|
| 310 |
+
|
| 311 |
+
AGENT_TRACES_FEATURES_MARKERS = {
|
| 312 |
+
"claude_code": datasets.Features(
|
| 313 |
+
{
|
| 314 |
+
"type": datasets.Value("string"),
|
| 315 |
+
"message": datasets.Json(),
|
| 316 |
+
}
|
| 317 |
+
),
|
| 318 |
+
"pi": datasets.Features(
|
| 319 |
+
{
|
| 320 |
+
"type": datasets.Value("string"),
|
| 321 |
+
"message": datasets.Json(),
|
| 322 |
+
}
|
| 323 |
+
),
|
| 324 |
+
"codex": datasets.Features(
|
| 325 |
+
{
|
| 326 |
+
"type": datasets.Value("string"),
|
| 327 |
+
"payload": datasets.Json(),
|
| 328 |
+
}
|
| 329 |
+
),
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
AGENT_TRACES_FEATURES = datasets.Features(
|
| 333 |
+
{
|
| 334 |
+
"harness": datasets.Value("string"),
|
| 335 |
+
"session_id": datasets.Value("string"),
|
| 336 |
+
"traces": datasets.List(datasets.Json()),
|
| 337 |
+
"file_path": datasets.Value("string"),
|
| 338 |
+
}
|
| 339 |
+
)
|
| 340 |
+
|
| 341 |
+
|
| 342 |
+
def has_agent_traces_markers(features: datasets.Features) -> bool:
|
| 343 |
+
for agent_traces_features_marker in AGENT_TRACES_FEATURES_MARKERS.values():
|
| 344 |
+
if all(features.get(key) == feature for key, feature in agent_traces_features_marker.items()):
|
| 345 |
+
return True
|
| 346 |
+
return False
|
| 347 |
+
|
| 348 |
+
|
| 349 |
+
def parse_traces_info(traces: list[str]) -> tuple[Optional[str], Optional[str]]:
|
| 350 |
+
harness, session_id = None, None
|
| 351 |
+
for trace in traces:
|
| 352 |
+
decoded_trace = ujson_loads(trace)
|
| 353 |
+
if harness is None:
|
| 354 |
+
if "type" in decoded_trace and isinstance(decoded_trace["type"], str):
|
| 355 |
+
harness = AGENT_TRACES_TYPE_TO_HARNESS.get(decoded_trace["type"])
|
| 356 |
+
if session_id is None:
|
| 357 |
+
# claude
|
| 358 |
+
if "sessionId" in decoded_trace and isinstance(decoded_trace["sessionId"], str):
|
| 359 |
+
session_id = decoded_trace["sessionId"]
|
| 360 |
+
# claude (not sure but this format does exist online)
|
| 361 |
+
elif "session_id" in decoded_trace and isinstance(decoded_trace["session_id"], str):
|
| 362 |
+
session_id = decoded_trace["session_id"]
|
| 363 |
+
# codex
|
| 364 |
+
elif (
|
| 365 |
+
"payload" in decoded_trace
|
| 366 |
+
and isinstance(decoded_trace["payload"], dict)
|
| 367 |
+
and "id" in decoded_trace["payload"]
|
| 368 |
+
and isinstance(decoded_trace["payload"]["id"], str)
|
| 369 |
+
):
|
| 370 |
+
session_id = decoded_trace["payload"]["id"]
|
| 371 |
+
# pi / openclaw (openclaw embeds pi-agent; distinguish via cwd)
|
| 372 |
+
elif (
|
| 373 |
+
"type" in decoded_trace
|
| 374 |
+
and decoded_trace["type"] == "session"
|
| 375 |
+
and "id" in decoded_trace
|
| 376 |
+
and isinstance(decoded_trace["id"], str)
|
| 377 |
+
):
|
| 378 |
+
session_id = decoded_trace["id"]
|
| 379 |
+
if isinstance(decoded_trace.get("cwd"), str) and "/.openclaw/" in decoded_trace["cwd"]:
|
| 380 |
+
harness = "openclaw"
|
| 381 |
+
if harness and session_id:
|
| 382 |
+
break
|
| 383 |
+
return harness, session_id
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/lance/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/lance/lance.py
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import re
|
| 2 |
+
from dataclasses import dataclass
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
from typing import TYPE_CHECKING, Dict, List, Optional
|
| 5 |
+
|
| 6 |
+
import pyarrow as pa
|
| 7 |
+
from huggingface_hub import HfApi
|
| 8 |
+
|
| 9 |
+
import datasets
|
| 10 |
+
from datasets import Audio, Image, Video
|
| 11 |
+
from datasets.builder import Key
|
| 12 |
+
from datasets.table import table_cast
|
| 13 |
+
from datasets.utils.file_utils import is_local_path
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
if TYPE_CHECKING:
|
| 17 |
+
import lance
|
| 18 |
+
import lance.file
|
| 19 |
+
|
| 20 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 21 |
+
|
| 22 |
+
MAGIC_BYTES_EXTENSION_AND_FEATURE_TYPES = [
|
| 23 |
+
("1A 45 DF A3", ".mkv", Video()),
|
| 24 |
+
("66 74 79 70 69 73 6F 6D", ".mp4", Video()),
|
| 25 |
+
("66 74 79 70 4D 53 4E 56", ".mp4", Video()),
|
| 26 |
+
("52 49 46 46", ".avi", Video()),
|
| 27 |
+
("00 00 01 BA", ".mpeg", Video()),
|
| 28 |
+
("00 00 01 BA", ".mpeg", Video()),
|
| 29 |
+
("00 00 01 B3", ".mov", Video()),
|
| 30 |
+
("89 50 4E 47", ".png", Image()),
|
| 31 |
+
("FF D8", ".jpg", Image()),
|
| 32 |
+
("49 49", ".tif", Image()),
|
| 33 |
+
("47 49 46 38", ".gif", Image()),
|
| 34 |
+
("52 49 46 46", ".wav", Audio()),
|
| 35 |
+
("49 44 33", ".mp3", Audio()),
|
| 36 |
+
("66 4C 61 43", ".flac", Audio()),
|
| 37 |
+
]
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
@dataclass
|
| 41 |
+
class LanceConfig(datasets.BuilderConfig):
|
| 42 |
+
"""
|
| 43 |
+
BuilderConfig for Lance format.
|
| 44 |
+
|
| 45 |
+
Args:
|
| 46 |
+
features: (`Features`, *optional*):
|
| 47 |
+
Cast the data to `features`.
|
| 48 |
+
columns: (`List[str]`, *optional*):
|
| 49 |
+
List of columns to load, the other ones are ignored.
|
| 50 |
+
batch_size: (`int`, *optional*):
|
| 51 |
+
Size of the RecordBatches to iterate on. Default to 256.
|
| 52 |
+
token: (`str`, *optional*):
|
| 53 |
+
Optional HF token to use to download datasets.
|
| 54 |
+
"""
|
| 55 |
+
|
| 56 |
+
features: Optional[datasets.Features] = None
|
| 57 |
+
columns: Optional[List[str]] = None
|
| 58 |
+
batch_size: Optional[int] = 256
|
| 59 |
+
token: Optional[str] = None
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def resolve_dataset_uris(files: List[str]) -> Dict[str, List[str]]:
|
| 63 |
+
dataset_uris = set()
|
| 64 |
+
for file_path in files:
|
| 65 |
+
path = Path(file_path)
|
| 66 |
+
if path.parent.name in {"_transactions", "_indices", "_versions"}:
|
| 67 |
+
dataset_root = path.parent.parent
|
| 68 |
+
dataset_uris.add(str(dataset_root))
|
| 69 |
+
return list(dataset_uris)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def _fix_hf_uri(uri: str) -> str:
|
| 73 |
+
# replace the revision tag from hf uri
|
| 74 |
+
if "@" in uri:
|
| 75 |
+
matched = re.match(r"(hf://.+?)(@[0-9a-f]+)(/.*)", uri)
|
| 76 |
+
if matched:
|
| 77 |
+
uri = matched.group(1) + matched.group(3)
|
| 78 |
+
return uri
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def _fix_local_version_file(uri: str) -> str:
|
| 82 |
+
# replace symlinks with real files for _version
|
| 83 |
+
if "/_versions/" in uri and is_local_path(uri):
|
| 84 |
+
path = Path(uri)
|
| 85 |
+
if path.is_symlink():
|
| 86 |
+
data = path.read_bytes()
|
| 87 |
+
path.unlink()
|
| 88 |
+
path.write_bytes(data)
|
| 89 |
+
return uri
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
class Lance(datasets.ArrowBasedBuilder, datasets.builder._CountableBuilderMixin):
|
| 93 |
+
BUILDER_CONFIG_CLASS = LanceConfig
|
| 94 |
+
METADATA_EXTENSIONS = [".idx", ".txn", ".manifest"]
|
| 95 |
+
|
| 96 |
+
def _info(self):
|
| 97 |
+
return datasets.DatasetInfo(features=self.config.features)
|
| 98 |
+
|
| 99 |
+
def _split_generators(self, dl_manager):
|
| 100 |
+
import lance
|
| 101 |
+
import lance.file
|
| 102 |
+
|
| 103 |
+
if not self.config.data_files:
|
| 104 |
+
raise ValueError(f"At least one data file must be specified, but got data_files={self.config.data_files}")
|
| 105 |
+
if self.repo_id:
|
| 106 |
+
api = HfApi(**dl_manager.download_config.storage_options.get("hf", {}))
|
| 107 |
+
dataset_sha = api.dataset_info(self.repo_id).sha
|
| 108 |
+
if dataset_sha != self.hash:
|
| 109 |
+
raise NotImplementedError(
|
| 110 |
+
f"lance doesn't support loading other revisions than 'main' yet, but got {self.hash}"
|
| 111 |
+
)
|
| 112 |
+
data_files = dl_manager.download(self.config.data_files)
|
| 113 |
+
|
| 114 |
+
# TODO: remove once Lance supports HF links with revisions
|
| 115 |
+
data_files = {split: [_fix_hf_uri(file) for file in files] for split, files in data_files.items()}
|
| 116 |
+
# TODO: remove once Lance supports symlinks for _version files
|
| 117 |
+
data_files = {split: [_fix_local_version_file(file) for file in files] for split, files in data_files.items()}
|
| 118 |
+
|
| 119 |
+
splits: list[datasets.SplitGenerator] = []
|
| 120 |
+
for split_name, files in data_files.items():
|
| 121 |
+
storage_options = dl_manager.download_config.storage_options.get(files[0].split("://", 0)[0] + "://")
|
| 122 |
+
|
| 123 |
+
lance_dataset_uris = resolve_dataset_uris(files)
|
| 124 |
+
if lance_dataset_uris:
|
| 125 |
+
lance_datasets = [lance.dataset(uri, storage_options=storage_options) for uri in lance_dataset_uris]
|
| 126 |
+
fragments = [frag for lance_dataset in lance_datasets for frag in lance_dataset.get_fragments()]
|
| 127 |
+
if self.info.features is None:
|
| 128 |
+
pa_schema = fragments[0]._ds.schema
|
| 129 |
+
first_row_first_bytes = {}
|
| 130 |
+
for field in pa_schema:
|
| 131 |
+
if self.config.columns is not None and field.name not in self.config.columns:
|
| 132 |
+
continue
|
| 133 |
+
if pa.types.is_binary(field.type) or pa.types.is_large_binary(field.type):
|
| 134 |
+
try:
|
| 135 |
+
first_row_first_bytes[field.name] = (
|
| 136 |
+
lance_datasets[0].take_blobs(field.name, [0])[0].read(16)
|
| 137 |
+
)
|
| 138 |
+
except ValueError:
|
| 139 |
+
first_row_first_bytes[field.name] = (
|
| 140 |
+
lance_datasets[0].take([0], [field.name]).to_pylist()[0][field.name][:16]
|
| 141 |
+
)
|
| 142 |
+
splits.append(
|
| 143 |
+
datasets.SplitGenerator(
|
| 144 |
+
name=split_name,
|
| 145 |
+
gen_kwargs={"fragments": fragments, "lance_files_paths": None, "lance_files": None},
|
| 146 |
+
)
|
| 147 |
+
)
|
| 148 |
+
else:
|
| 149 |
+
lance_files = [
|
| 150 |
+
lance.file.LanceFileReader(file, storage_options=storage_options, columns=self.config.columns)
|
| 151 |
+
for file in files
|
| 152 |
+
]
|
| 153 |
+
if self.info.features is None:
|
| 154 |
+
pa_schema = lance_files[0].metadata().schema
|
| 155 |
+
first_row_first_bytes = {
|
| 156 |
+
field_name: value[:16]
|
| 157 |
+
for field_name, value in lance_files[0].take_rows([0]).to_table().to_pylist()[0].items()
|
| 158 |
+
if isinstance(value, bytes)
|
| 159 |
+
}
|
| 160 |
+
splits.append(
|
| 161 |
+
datasets.SplitGenerator(
|
| 162 |
+
name=split_name,
|
| 163 |
+
gen_kwargs={"fragments": None, "lance_files_paths": files, "lance_files": lance_files},
|
| 164 |
+
)
|
| 165 |
+
)
|
| 166 |
+
if self.info.features is None:
|
| 167 |
+
if self.config.columns:
|
| 168 |
+
fields = [
|
| 169 |
+
pa_schema.field(name) for name in self.config.columns if pa_schema.get_field_index(name) != -1
|
| 170 |
+
]
|
| 171 |
+
pa_schema = pa.schema(fields)
|
| 172 |
+
features = datasets.Features.from_arrow_schema(pa_schema)
|
| 173 |
+
for field_name, first_bytes in first_row_first_bytes.items():
|
| 174 |
+
for magic_bytes_hex, _, feature_type in MAGIC_BYTES_EXTENSION_AND_FEATURE_TYPES:
|
| 175 |
+
magic_bytes = bytes.fromhex(magic_bytes_hex)
|
| 176 |
+
if magic_bytes in first_bytes[: len(magic_bytes) * 2]: # allow some padding
|
| 177 |
+
features[field_name] = feature_type
|
| 178 |
+
break
|
| 179 |
+
self.info.features = features
|
| 180 |
+
|
| 181 |
+
return splits
|
| 182 |
+
|
| 183 |
+
def _cast_table(self, pa_table: pa.Table) -> pa.Table:
|
| 184 |
+
if self.info.features is not None:
|
| 185 |
+
# more expensive cast to support nested features with keys in a different order
|
| 186 |
+
# allows str <-> int/float or str to Audio for example
|
| 187 |
+
pa_table = table_cast(pa_table, self.info.features.arrow_schema)
|
| 188 |
+
return pa_table
|
| 189 |
+
|
| 190 |
+
def _generate_shards(
|
| 191 |
+
self,
|
| 192 |
+
fragments: Optional[List["lance.LanceFragment"]],
|
| 193 |
+
lance_files_paths: Optional[list[str]],
|
| 194 |
+
lance_files: Optional[List["lance.file.LanceFileReader"]],
|
| 195 |
+
):
|
| 196 |
+
if fragments:
|
| 197 |
+
for fragment in fragments:
|
| 198 |
+
paths = [data_file.path for data_file in fragment.metadata.data_files()]
|
| 199 |
+
yield paths[0] if len(paths) == 1 else {"fragment_data_files": paths}
|
| 200 |
+
else:
|
| 201 |
+
yield from lance_files_paths
|
| 202 |
+
|
| 203 |
+
def _generate_num_examples(
|
| 204 |
+
self,
|
| 205 |
+
fragments: Optional[List["lance.LanceFragment"]],
|
| 206 |
+
lance_files_paths: Optional[list[str]],
|
| 207 |
+
lance_files: Optional[List["lance.file.LanceFileReader"]],
|
| 208 |
+
):
|
| 209 |
+
if fragments:
|
| 210 |
+
for fragment in fragments:
|
| 211 |
+
yield fragment.count_rows()
|
| 212 |
+
else:
|
| 213 |
+
for lance_file in lance_files:
|
| 214 |
+
yield lance_file.num_rows()
|
| 215 |
+
|
| 216 |
+
def _generate_tables(
|
| 217 |
+
self,
|
| 218 |
+
fragments: Optional[List["lance.LanceFragment"]],
|
| 219 |
+
lance_files_paths: Optional[list[str]],
|
| 220 |
+
lance_files: Optional[List["lance.file.LanceFileReader"]],
|
| 221 |
+
):
|
| 222 |
+
if fragments:
|
| 223 |
+
for frag_idx, fragment in enumerate(fragments):
|
| 224 |
+
for batch_idx, batch in enumerate(
|
| 225 |
+
fragment.to_batches(
|
| 226 |
+
columns=self.config.columns, batch_size=self.config.batch_size, blob_handling="all_binary"
|
| 227 |
+
)
|
| 228 |
+
):
|
| 229 |
+
table = pa.Table.from_batches([batch])
|
| 230 |
+
yield Key(frag_idx, batch_idx), self._cast_table(table)
|
| 231 |
+
else:
|
| 232 |
+
for file_idx, lance_file in enumerate(lance_files):
|
| 233 |
+
for batch_idx, batch in enumerate(lance_file.read_all(batch_size=self.config.batch_size).to_batches()):
|
| 234 |
+
table = pa.Table.from_batches([batch])
|
| 235 |
+
yield Key(file_idx, batch_idx), self._cast_table(table)
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/niftifolder/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/niftifolder/niftifolder.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import datasets
|
| 2 |
+
|
| 3 |
+
from ..folder_based_builder import folder_based_builder
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class NiftiFolderConfig(folder_based_builder.FolderBasedBuilderConfig):
|
| 10 |
+
"""BuilderConfig for NiftiFolder."""
|
| 11 |
+
|
| 12 |
+
drop_labels: bool = None
|
| 13 |
+
drop_metadata: bool = None
|
| 14 |
+
|
| 15 |
+
def __post_init__(self):
|
| 16 |
+
super().__post_init__()
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class NiftiFolder(folder_based_builder.FolderBasedBuilder):
|
| 20 |
+
BASE_FEATURE = datasets.Nifti
|
| 21 |
+
BASE_COLUMN_NAME = "nifti"
|
| 22 |
+
BUILDER_CONFIG_CLASS = NiftiFolderConfig
|
| 23 |
+
EXTENSIONS: list[str] = [".nii"]
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/parquet/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/parquet/parquet.py
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from dataclasses import dataclass
|
| 2 |
+
from typing import Literal, Optional, Union
|
| 3 |
+
|
| 4 |
+
import pyarrow as pa
|
| 5 |
+
import pyarrow.dataset as ds
|
| 6 |
+
import pyarrow.parquet as pq
|
| 7 |
+
|
| 8 |
+
import datasets
|
| 9 |
+
from datasets.builder import Key
|
| 10 |
+
from datasets.table import table_cast
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
@dataclass
|
| 17 |
+
class ParquetConfig(datasets.BuilderConfig):
|
| 18 |
+
"""
|
| 19 |
+
BuilderConfig for Parquet.
|
| 20 |
+
|
| 21 |
+
Args:
|
| 22 |
+
batch_size (`int`, *optional*):
|
| 23 |
+
Size of the RecordBatches to iterate on.
|
| 24 |
+
The default is the row group size (defined by the first row group).
|
| 25 |
+
columns (`list[str]`, *optional*)
|
| 26 |
+
List of columns to load, the other ones are ignored.
|
| 27 |
+
All columns are loaded by default.
|
| 28 |
+
features: (`Features`, *optional*):
|
| 29 |
+
Cast the data to `features`.
|
| 30 |
+
filters (`Union[pyarrow.dataset.Expression, list[tuple], list[list[tuple]]]`, *optional*):
|
| 31 |
+
Return only the rows matching the filter.
|
| 32 |
+
If possible the predicate will be pushed down to exploit the partition information
|
| 33 |
+
or internal metadata found in the data source, e.g. Parquet statistics.
|
| 34 |
+
Otherwise filters the loaded RecordBatches before yielding them.
|
| 35 |
+
fragment_scan_options (`pyarrow.dataset.ParquetFragmentScanOptions`, *optional*)
|
| 36 |
+
Scan-specific options for Parquet fragments.
|
| 37 |
+
This is especially useful to configure buffering and caching.
|
| 38 |
+
|
| 39 |
+
<Added version="4.2.0"/>
|
| 40 |
+
on_bad_files (`Literal["error", "warn", "skip"]`, *optional*, defaults to "error")
|
| 41 |
+
Specify what to do upon encountering a bad file (a file that can't be read). Allowed values are :
|
| 42 |
+
* 'error', raise an Exception when a bad file is encountered.
|
| 43 |
+
* 'warn', raise a warning when a bad file is encountered and skip that file.
|
| 44 |
+
* 'skip', skip bad files without raising or warning when they are encountered.
|
| 45 |
+
|
| 46 |
+
<Added version="4.2.0"/>
|
| 47 |
+
|
| 48 |
+
Example:
|
| 49 |
+
|
| 50 |
+
Load a subset of columns:
|
| 51 |
+
|
| 52 |
+
```python
|
| 53 |
+
>>> ds = load_dataset(parquet_dataset_id, columns=["col_0", "col_1"])
|
| 54 |
+
```
|
| 55 |
+
|
| 56 |
+
Stream data and efficiently filter data, possibly skipping entire files or row groups:
|
| 57 |
+
|
| 58 |
+
```python
|
| 59 |
+
>>> filters = [("col_0", "==", 0)]
|
| 60 |
+
>>> ds = load_dataset(parquet_dataset_id, streaming=True, filters=filters)
|
| 61 |
+
```
|
| 62 |
+
|
| 63 |
+
Increase the minimum request size when streaming from 32MiB (default) to 128MiB and enable prefetching:
|
| 64 |
+
|
| 65 |
+
```python
|
| 66 |
+
>>> import pyarrow
|
| 67 |
+
>>> import pyarrow.dataset
|
| 68 |
+
>>> fragment_scan_options = pyarrow.dataset.ParquetFragmentScanOptions(
|
| 69 |
+
... cache_options=pyarrow.CacheOptions(
|
| 70 |
+
... prefetch_limit=1,
|
| 71 |
+
... range_size_limit=128 << 20
|
| 72 |
+
... ),
|
| 73 |
+
... )
|
| 74 |
+
>>> ds = load_dataset(parquet_dataset_id, streaming=True, fragment_scan_options=fragment_scan_options)
|
| 75 |
+
```
|
| 76 |
+
|
| 77 |
+
"""
|
| 78 |
+
|
| 79 |
+
batch_size: Optional[int] = None
|
| 80 |
+
columns: Optional[list[str]] = None
|
| 81 |
+
features: Optional[datasets.Features] = None
|
| 82 |
+
filters: Optional[Union[ds.Expression, list[tuple], list[list[tuple]]]] = None
|
| 83 |
+
fragment_scan_options: Optional[ds.ParquetFragmentScanOptions] = None
|
| 84 |
+
on_bad_files: Literal["error", "warn", "skip"] = "error"
|
| 85 |
+
|
| 86 |
+
def __post_init__(self):
|
| 87 |
+
super().__post_init__()
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
class Parquet(datasets.ArrowBasedBuilder):
|
| 91 |
+
BUILDER_CONFIG_CLASS = ParquetConfig
|
| 92 |
+
|
| 93 |
+
def _info(self):
|
| 94 |
+
if (
|
| 95 |
+
self.config.columns is not None
|
| 96 |
+
and self.config.features is not None
|
| 97 |
+
and set(self.config.columns) != set(self.config.features)
|
| 98 |
+
):
|
| 99 |
+
raise ValueError(
|
| 100 |
+
"The columns and features argument must contain the same columns, but got ",
|
| 101 |
+
f"{self.config.columns} and {self.config.features}",
|
| 102 |
+
)
|
| 103 |
+
return datasets.DatasetInfo(features=self.config.features)
|
| 104 |
+
|
| 105 |
+
def _split_generators(self, dl_manager):
|
| 106 |
+
"""We handle string, list and dicts in datafiles"""
|
| 107 |
+
if not self.config.data_files:
|
| 108 |
+
raise ValueError(f"At least one data file must be specified, but got data_files={self.config.data_files}")
|
| 109 |
+
dl_manager.download_config.extract_on_the_fly = True
|
| 110 |
+
data_files = dl_manager.download(self.config.data_files)
|
| 111 |
+
splits = []
|
| 112 |
+
for split_name, files in data_files.items():
|
| 113 |
+
# Infer features if they are stored in the arrow schema
|
| 114 |
+
if self.info.features is None:
|
| 115 |
+
for file in files:
|
| 116 |
+
try:
|
| 117 |
+
with open(file, "rb") as f:
|
| 118 |
+
self.info.features = datasets.Features.from_arrow_schema(pq.read_schema(f))
|
| 119 |
+
break
|
| 120 |
+
except pa.ArrowInvalid as e:
|
| 121 |
+
if self.config.on_bad_files == "error":
|
| 122 |
+
logger.error(f"Failed to read schema from '{file}' with error {type(e).__name__}: {e}")
|
| 123 |
+
raise
|
| 124 |
+
elif self.config.on_bad_files == "warn":
|
| 125 |
+
logger.warning(f"Skipping bad schema from '{file}'. {type(e).__name__}: {e}`")
|
| 126 |
+
else:
|
| 127 |
+
logger.debug(f"Skipping bad schema from '{file}'. {type(e).__name__}: {e}`")
|
| 128 |
+
if self.info.features is None:
|
| 129 |
+
raise ValueError(
|
| 130 |
+
f"At least one valid data file must be specified, all the data_files are invalid: {self.config.data_files}"
|
| 131 |
+
)
|
| 132 |
+
splits.append(
|
| 133 |
+
datasets.SplitGenerator(
|
| 134 |
+
name=split_name, gen_kwargs={"files": files, "row_groups_list": [None] * len(files)}
|
| 135 |
+
)
|
| 136 |
+
)
|
| 137 |
+
if self.config.columns is not None and set(self.config.columns) != set(self.info.features):
|
| 138 |
+
self.info.features = datasets.Features(
|
| 139 |
+
{col: feat for col, feat in self.info.features.items() if col in self.config.columns}
|
| 140 |
+
)
|
| 141 |
+
return splits
|
| 142 |
+
|
| 143 |
+
def _cast_table(self, pa_table: pa.Table) -> pa.Table:
|
| 144 |
+
if self.info.features is not None:
|
| 145 |
+
# more expensive cast to support nested features with keys in a different order
|
| 146 |
+
# allows str <-> int/float or str to Audio for example
|
| 147 |
+
pa_table = table_cast(pa_table, self.info.features.arrow_schema)
|
| 148 |
+
return pa_table
|
| 149 |
+
|
| 150 |
+
def _generate_shards(self, files, row_groups_list):
|
| 151 |
+
if not row_groups_list:
|
| 152 |
+
yield from files
|
| 153 |
+
else:
|
| 154 |
+
for file, row_groups in zip(files, row_groups_list):
|
| 155 |
+
yield {
|
| 156 |
+
"fragment_data_file": file,
|
| 157 |
+
"fragment_row_groups": row_groups,
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
def _generate_more_gen_kwargs(self, files, row_groups_list):
|
| 161 |
+
if not row_groups_list:
|
| 162 |
+
parquet_file_format = ds.ParquetFileFormat(default_fragment_scan_options=self.config.fragment_scan_options)
|
| 163 |
+
for file in files:
|
| 164 |
+
with open(file, "rb") as f:
|
| 165 |
+
parquet_fragment = parquet_file_format.make_fragment(f)
|
| 166 |
+
yield {
|
| 167 |
+
"files": [file] * parquet_fragment.num_row_groups,
|
| 168 |
+
"row_groups_list": [
|
| 169 |
+
(row_group_id,) for row_group_id in range(parquet_fragment.num_row_groups)
|
| 170 |
+
],
|
| 171 |
+
}
|
| 172 |
+
else:
|
| 173 |
+
for file, row_groups in zip(files, row_groups_list):
|
| 174 |
+
yield {"files": [file], "row_groups_list": [row_groups]}
|
| 175 |
+
|
| 176 |
+
def _generate_tables(self, files, row_groups_list):
|
| 177 |
+
if self.config.features is not None and self.config.columns is not None:
|
| 178 |
+
if sorted(field.name for field in self.info.features.arrow_schema) != sorted(self.config.columns):
|
| 179 |
+
raise ValueError(
|
| 180 |
+
f"Tried to load parquet data with columns '{self.config.columns}' with mismatching features '{self.info.features}'"
|
| 181 |
+
)
|
| 182 |
+
filter_expr = (
|
| 183 |
+
pq.filters_to_expression(self.config.filters)
|
| 184 |
+
if isinstance(self.config.filters, list)
|
| 185 |
+
else self.config.filters
|
| 186 |
+
)
|
| 187 |
+
parquet_file_format = ds.ParquetFileFormat(default_fragment_scan_options=self.config.fragment_scan_options)
|
| 188 |
+
for file_idx, (file, row_groups) in enumerate(zip(files, row_groups_list)):
|
| 189 |
+
try:
|
| 190 |
+
with open(file, "rb") as f:
|
| 191 |
+
parquet_fragment = parquet_file_format.make_fragment(f)
|
| 192 |
+
if row_groups is not None:
|
| 193 |
+
parquet_fragment.subset(row_group_ids=row_groups)
|
| 194 |
+
if parquet_fragment.row_groups:
|
| 195 |
+
batch_size = self.config.batch_size or parquet_fragment.row_groups[0].num_rows
|
| 196 |
+
for batch_idx, record_batch in enumerate(
|
| 197 |
+
parquet_fragment.to_batches(
|
| 198 |
+
batch_size=batch_size,
|
| 199 |
+
columns=self.config.columns,
|
| 200 |
+
filter=filter_expr,
|
| 201 |
+
batch_readahead=0,
|
| 202 |
+
fragment_readahead=0,
|
| 203 |
+
)
|
| 204 |
+
):
|
| 205 |
+
pa_table = pa.Table.from_batches([record_batch])
|
| 206 |
+
# Uncomment for debugging (will print the Arrow table size and elements)
|
| 207 |
+
# logger.warning(f"pa_table: {pa_table} num rows: {pa_table.num_rows}")
|
| 208 |
+
# logger.warning('\n'.join(str(pa_table.slice(i, 1).to_pydict()) for i in range(pa_table.num_rows)))
|
| 209 |
+
yield Key(file_idx, batch_idx), self._cast_table(pa_table)
|
| 210 |
+
except (pa.ArrowInvalid, ValueError) as e:
|
| 211 |
+
if self.config.on_bad_files == "error":
|
| 212 |
+
logger.error(f"Failed to read file '{file}' with error {type(e).__name__}: {e}")
|
| 213 |
+
raise
|
| 214 |
+
elif self.config.on_bad_files == "warn":
|
| 215 |
+
logger.warning(f"Skipping bad file '{file}'. {type(e).__name__}: {e}`")
|
| 216 |
+
else:
|
| 217 |
+
logger.debug(f"Skipping bad file '{file}'. {type(e).__name__}: {e}`")
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/spark/spark.py
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import posixpath
|
| 3 |
+
import uuid
|
| 4 |
+
from collections.abc import Iterable
|
| 5 |
+
from dataclasses import dataclass
|
| 6 |
+
from itertools import islice
|
| 7 |
+
from typing import TYPE_CHECKING, Optional, Union
|
| 8 |
+
|
| 9 |
+
import numpy as np
|
| 10 |
+
import pyarrow as pa
|
| 11 |
+
|
| 12 |
+
import datasets
|
| 13 |
+
from datasets.arrow_writer import ArrowWriter, ParquetWriter
|
| 14 |
+
from datasets.config import MAX_SHARD_SIZE
|
| 15 |
+
from datasets.filesystems import (
|
| 16 |
+
is_remote_filesystem,
|
| 17 |
+
rename,
|
| 18 |
+
)
|
| 19 |
+
from datasets.iterable_dataset import _BaseExamplesIterable
|
| 20 |
+
from datasets.utils import experimental
|
| 21 |
+
from datasets.utils.py_utils import convert_file_size_to_int
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 25 |
+
|
| 26 |
+
if TYPE_CHECKING:
|
| 27 |
+
import pyspark
|
| 28 |
+
import pyspark.sql
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
@dataclass
|
| 32 |
+
class SparkConfig(datasets.BuilderConfig):
|
| 33 |
+
"""BuilderConfig for Spark."""
|
| 34 |
+
|
| 35 |
+
features: Optional[datasets.Features] = None
|
| 36 |
+
|
| 37 |
+
def __post_init__(self):
|
| 38 |
+
super().__post_init__()
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def _reorder_dataframe_by_partition(df: "pyspark.sql.DataFrame", new_partition_order: list[int]):
|
| 42 |
+
df_combined = df.select("*").where(f"part_id = {new_partition_order[0]}")
|
| 43 |
+
for partition_id in new_partition_order[1:]:
|
| 44 |
+
partition_df = df.select("*").where(f"part_id = {partition_id}")
|
| 45 |
+
df_combined = df_combined.union(partition_df)
|
| 46 |
+
return df_combined
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def _generate_iterable_examples(
|
| 50 |
+
df: "pyspark.sql.DataFrame",
|
| 51 |
+
partition_order: list[int],
|
| 52 |
+
state_dict: Optional[dict] = None,
|
| 53 |
+
):
|
| 54 |
+
import pyspark
|
| 55 |
+
|
| 56 |
+
df_with_partition_id = df.select("*", pyspark.sql.functions.spark_partition_id().alias("part_id"))
|
| 57 |
+
partition_idx_start = state_dict["partition_idx"] if state_dict else 0
|
| 58 |
+
partition_df = _reorder_dataframe_by_partition(df_with_partition_id, partition_order[partition_idx_start:])
|
| 59 |
+
# pipeline next partition in parallel to hide latency
|
| 60 |
+
rows = partition_df.toLocalIterator(prefetchPartitions=True)
|
| 61 |
+
curr_partition = None
|
| 62 |
+
row_id = state_dict["partition_example_idx"] if state_dict else 0
|
| 63 |
+
for row in islice(rows, row_id, None):
|
| 64 |
+
row_as_dict = row.asDict()
|
| 65 |
+
part_id = row_as_dict["part_id"]
|
| 66 |
+
row_as_dict.pop("part_id")
|
| 67 |
+
if curr_partition != part_id:
|
| 68 |
+
if state_dict and curr_partition is not None:
|
| 69 |
+
state_dict["partition_idx"] += 1
|
| 70 |
+
curr_partition = part_id
|
| 71 |
+
row_id = 0
|
| 72 |
+
if state_dict:
|
| 73 |
+
state_dict["partition_example_idx"] = row_id + 1
|
| 74 |
+
yield (part_id, row_id), row_as_dict
|
| 75 |
+
row_id += 1
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
class SparkExamplesIterable(_BaseExamplesIterable):
|
| 79 |
+
def __init__(
|
| 80 |
+
self,
|
| 81 |
+
df: "pyspark.sql.DataFrame",
|
| 82 |
+
partition_order=None,
|
| 83 |
+
):
|
| 84 |
+
super().__init__()
|
| 85 |
+
self.df = df
|
| 86 |
+
self.partition_order = partition_order or range(self.df.rdd.getNumPartitions())
|
| 87 |
+
|
| 88 |
+
def _init_state_dict(self) -> dict:
|
| 89 |
+
self._state_dict = {"partition_idx": 0, "partition_example_idx": 0}
|
| 90 |
+
return self._state_dict
|
| 91 |
+
|
| 92 |
+
@experimental
|
| 93 |
+
def load_state_dict(self, state_dict: dict) -> dict:
|
| 94 |
+
return super().load_state_dict(state_dict)
|
| 95 |
+
|
| 96 |
+
def __iter__(self):
|
| 97 |
+
yield from _generate_iterable_examples(self.df, self.partition_order, self._state_dict)
|
| 98 |
+
|
| 99 |
+
def shuffle_data_sources(self, generator: np.random.Generator) -> "SparkExamplesIterable":
|
| 100 |
+
partition_order = list(range(self.df.rdd.getNumPartitions()))
|
| 101 |
+
generator.shuffle(partition_order)
|
| 102 |
+
return SparkExamplesIterable(self.df, partition_order=partition_order)
|
| 103 |
+
|
| 104 |
+
def shard_data_sources(self, num_shards: int, index: int, contiguous=True) -> "SparkExamplesIterable":
|
| 105 |
+
partition_order = self.split_shard_indices_by_worker(num_shards=num_shards, index=index, contiguous=contiguous)
|
| 106 |
+
return SparkExamplesIterable(self.df, partition_order=partition_order)
|
| 107 |
+
|
| 108 |
+
@property
|
| 109 |
+
def num_shards(self) -> int:
|
| 110 |
+
return len(self.partition_order)
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
class Spark(datasets.DatasetBuilder):
|
| 114 |
+
BUILDER_CONFIG_CLASS = SparkConfig
|
| 115 |
+
|
| 116 |
+
def __init__(
|
| 117 |
+
self,
|
| 118 |
+
df: "pyspark.sql.DataFrame",
|
| 119 |
+
cache_dir: str = None,
|
| 120 |
+
working_dir: str = None,
|
| 121 |
+
**config_kwargs,
|
| 122 |
+
):
|
| 123 |
+
import pyspark
|
| 124 |
+
|
| 125 |
+
self._spark = pyspark.sql.SparkSession.builder.getOrCreate()
|
| 126 |
+
self.df = df
|
| 127 |
+
self._working_dir = working_dir
|
| 128 |
+
|
| 129 |
+
super().__init__(
|
| 130 |
+
cache_dir=cache_dir,
|
| 131 |
+
config_name=str(self.df.semanticHash()),
|
| 132 |
+
**config_kwargs,
|
| 133 |
+
)
|
| 134 |
+
|
| 135 |
+
def _validate_cache_dir(self):
|
| 136 |
+
# Define this so that we don't reference self in create_cache_and_write_probe, which will result in a pickling
|
| 137 |
+
# error due to pickling the SparkContext.
|
| 138 |
+
cache_dir = self._cache_dir
|
| 139 |
+
|
| 140 |
+
# Returns the path of the created file.
|
| 141 |
+
def create_cache_and_write_probe(context):
|
| 142 |
+
# makedirs with exist_ok will recursively create the directory. It will not throw an error if directories
|
| 143 |
+
# already exist.
|
| 144 |
+
os.makedirs(cache_dir, exist_ok=True)
|
| 145 |
+
probe_file = os.path.join(cache_dir, "fs_test" + uuid.uuid4().hex)
|
| 146 |
+
# Opening the file in append mode will create a new file unless it already exists, in which case it will not
|
| 147 |
+
# change the file contents.
|
| 148 |
+
open(probe_file, "a")
|
| 149 |
+
return [probe_file]
|
| 150 |
+
|
| 151 |
+
if self._spark.conf.get("spark.master", "").startswith("local"):
|
| 152 |
+
return
|
| 153 |
+
|
| 154 |
+
# If the cluster is multi-node, make sure that the user provided a cache_dir and that it is on an NFS
|
| 155 |
+
# accessible to the driver.
|
| 156 |
+
# TODO: Stream batches to the driver using ArrowCollectSerializer instead of throwing an error.
|
| 157 |
+
if self._cache_dir:
|
| 158 |
+
probe = (
|
| 159 |
+
self._spark.sparkContext.parallelize(range(1), 1).mapPartitions(create_cache_and_write_probe).collect()
|
| 160 |
+
)
|
| 161 |
+
if os.path.isfile(probe[0]):
|
| 162 |
+
return
|
| 163 |
+
|
| 164 |
+
raise ValueError(
|
| 165 |
+
"When using Dataset.from_spark on a multi-node cluster, the driver and all workers should be able to access cache_dir"
|
| 166 |
+
)
|
| 167 |
+
|
| 168 |
+
def _info(self):
|
| 169 |
+
return datasets.DatasetInfo(features=self.config.features)
|
| 170 |
+
|
| 171 |
+
def _split_generators(self, dl_manager: datasets.download.download_manager.DownloadManager):
|
| 172 |
+
return [datasets.SplitGenerator(name=datasets.Split.TRAIN)]
|
| 173 |
+
|
| 174 |
+
def _repartition_df_if_needed(self, max_shard_size):
|
| 175 |
+
import pyspark
|
| 176 |
+
|
| 177 |
+
def get_arrow_batch_size(it):
|
| 178 |
+
for batch in it:
|
| 179 |
+
yield pa.RecordBatch.from_pydict({"batch_bytes": [batch.nbytes]})
|
| 180 |
+
|
| 181 |
+
df_num_rows = self.df.count()
|
| 182 |
+
sample_num_rows = df_num_rows if df_num_rows <= 100 else 100
|
| 183 |
+
# Approximate the size of each row (in Arrow format) by averaging over a max-100-row sample.
|
| 184 |
+
approx_bytes_per_row = (
|
| 185 |
+
self.df.limit(sample_num_rows)
|
| 186 |
+
.repartition(1)
|
| 187 |
+
.mapInArrow(get_arrow_batch_size, "batch_bytes: long")
|
| 188 |
+
.agg(pyspark.sql.functions.sum("batch_bytes").alias("sample_bytes"))
|
| 189 |
+
.collect()[0]
|
| 190 |
+
.sample_bytes
|
| 191 |
+
/ sample_num_rows
|
| 192 |
+
)
|
| 193 |
+
approx_total_size = approx_bytes_per_row * df_num_rows
|
| 194 |
+
if approx_total_size > max_shard_size:
|
| 195 |
+
# Make sure there is at least one row per partition.
|
| 196 |
+
new_num_partitions = min(df_num_rows, int(approx_total_size / max_shard_size))
|
| 197 |
+
self.df = self.df.repartition(new_num_partitions)
|
| 198 |
+
|
| 199 |
+
def _prepare_split_single(
|
| 200 |
+
self,
|
| 201 |
+
fpath: str,
|
| 202 |
+
file_format: str,
|
| 203 |
+
max_shard_size: int,
|
| 204 |
+
) -> Iterable[tuple[int, bool, Union[int, tuple]]]:
|
| 205 |
+
import pyspark
|
| 206 |
+
|
| 207 |
+
writer_class = ParquetWriter if file_format == "parquet" else ArrowWriter
|
| 208 |
+
working_fpath = os.path.join(self._working_dir, os.path.basename(fpath)) if self._working_dir else fpath
|
| 209 |
+
embed_local_files = file_format == "parquet"
|
| 210 |
+
|
| 211 |
+
# Define these so that we don't reference self in write_arrow, which will result in a pickling error due to
|
| 212 |
+
# pickling the SparkContext.
|
| 213 |
+
features = self.config.features
|
| 214 |
+
writer_batch_size = self._writer_batch_size
|
| 215 |
+
storage_options = self._fs.storage_options
|
| 216 |
+
|
| 217 |
+
def write_arrow(it):
|
| 218 |
+
# Within the same SparkContext, no two task attempts will share the same attempt ID.
|
| 219 |
+
task_id = pyspark.TaskContext().taskAttemptId()
|
| 220 |
+
first_batch = next(it, None)
|
| 221 |
+
if first_batch is None:
|
| 222 |
+
# Some partitions might not receive any data.
|
| 223 |
+
return pa.RecordBatch.from_arrays(
|
| 224 |
+
[[task_id], [0], [0]],
|
| 225 |
+
names=["task_id", "num_examples", "num_bytes"],
|
| 226 |
+
)
|
| 227 |
+
shard_id = 0
|
| 228 |
+
writer = writer_class(
|
| 229 |
+
features=features,
|
| 230 |
+
path=working_fpath.replace("SSSSS", f"{shard_id:05d}").replace("TTTTT", f"{task_id:05d}"),
|
| 231 |
+
writer_batch_size=writer_batch_size,
|
| 232 |
+
storage_options=storage_options,
|
| 233 |
+
embed_local_files=embed_local_files,
|
| 234 |
+
)
|
| 235 |
+
table = pa.Table.from_batches([first_batch])
|
| 236 |
+
writer.write_table(table)
|
| 237 |
+
for batch in it:
|
| 238 |
+
if max_shard_size is not None and writer._num_bytes >= max_shard_size:
|
| 239 |
+
num_examples, num_bytes = writer.finalize()
|
| 240 |
+
writer.close()
|
| 241 |
+
yield pa.RecordBatch.from_arrays(
|
| 242 |
+
[[task_id], [num_examples], [num_bytes]],
|
| 243 |
+
names=["task_id", "num_examples", "num_bytes"],
|
| 244 |
+
)
|
| 245 |
+
shard_id += 1
|
| 246 |
+
writer = writer_class(
|
| 247 |
+
features=writer._features,
|
| 248 |
+
path=working_fpath.replace("SSSSS", f"{shard_id:05d}").replace("TTTTT", f"{task_id:05d}"),
|
| 249 |
+
writer_batch_size=writer_batch_size,
|
| 250 |
+
storage_options=storage_options,
|
| 251 |
+
embed_local_files=embed_local_files,
|
| 252 |
+
)
|
| 253 |
+
table = pa.Table.from_batches([batch])
|
| 254 |
+
writer.write_table(table)
|
| 255 |
+
|
| 256 |
+
if writer._num_bytes > 0:
|
| 257 |
+
num_examples, num_bytes = writer.finalize()
|
| 258 |
+
writer.close()
|
| 259 |
+
yield pa.RecordBatch.from_arrays(
|
| 260 |
+
[[task_id], [num_examples], [num_bytes]],
|
| 261 |
+
names=["task_id", "num_examples", "num_bytes"],
|
| 262 |
+
)
|
| 263 |
+
|
| 264 |
+
if working_fpath != fpath:
|
| 265 |
+
for file in os.listdir(os.path.dirname(working_fpath)):
|
| 266 |
+
dest = os.path.join(os.path.dirname(fpath), os.path.basename(file))
|
| 267 |
+
shutil.move(file, dest)
|
| 268 |
+
|
| 269 |
+
stats = (
|
| 270 |
+
self.df.mapInArrow(write_arrow, "task_id: long, num_examples: long, num_bytes: long")
|
| 271 |
+
.groupBy("task_id")
|
| 272 |
+
.agg(
|
| 273 |
+
pyspark.sql.functions.sum("num_examples").alias("total_num_examples"),
|
| 274 |
+
pyspark.sql.functions.sum("num_bytes").alias("total_num_bytes"),
|
| 275 |
+
pyspark.sql.functions.count("num_bytes").alias("num_shards"),
|
| 276 |
+
pyspark.sql.functions.collect_list("num_examples").alias("shard_lengths"),
|
| 277 |
+
)
|
| 278 |
+
.collect()
|
| 279 |
+
)
|
| 280 |
+
for row in stats:
|
| 281 |
+
yield row.task_id, (row.total_num_examples, row.total_num_bytes, row.num_shards, row.shard_lengths)
|
| 282 |
+
|
| 283 |
+
def _prepare_split(
|
| 284 |
+
self,
|
| 285 |
+
split_generator: "datasets.SplitGenerator",
|
| 286 |
+
file_format: str = "arrow",
|
| 287 |
+
max_shard_size: Optional[Union[str, int]] = None,
|
| 288 |
+
num_proc: Optional[int] = None,
|
| 289 |
+
**kwargs,
|
| 290 |
+
):
|
| 291 |
+
self._validate_cache_dir()
|
| 292 |
+
|
| 293 |
+
max_shard_size = convert_file_size_to_int(max_shard_size or MAX_SHARD_SIZE)
|
| 294 |
+
self._repartition_df_if_needed(max_shard_size)
|
| 295 |
+
is_local = not is_remote_filesystem(self._fs)
|
| 296 |
+
path_join = os.path.join if is_local else posixpath.join
|
| 297 |
+
|
| 298 |
+
SUFFIX = "-TTTTT-SSSSS-of-NNNNN"
|
| 299 |
+
fname = f"{self.name}-{split_generator.name}{SUFFIX}.{file_format}"
|
| 300 |
+
fpath = path_join(self._output_dir, fname)
|
| 301 |
+
|
| 302 |
+
total_num_examples = 0
|
| 303 |
+
total_num_bytes = 0
|
| 304 |
+
total_shards = 0
|
| 305 |
+
task_id_and_num_shards = []
|
| 306 |
+
all_shard_lengths = []
|
| 307 |
+
|
| 308 |
+
for task_id, content in self._prepare_split_single(fpath, file_format, max_shard_size):
|
| 309 |
+
(
|
| 310 |
+
num_examples,
|
| 311 |
+
num_bytes,
|
| 312 |
+
num_shards,
|
| 313 |
+
shard_lengths,
|
| 314 |
+
) = content
|
| 315 |
+
if num_bytes > 0:
|
| 316 |
+
total_num_examples += num_examples
|
| 317 |
+
total_num_bytes += num_bytes
|
| 318 |
+
total_shards += num_shards
|
| 319 |
+
task_id_and_num_shards.append((task_id, num_shards))
|
| 320 |
+
all_shard_lengths.extend(shard_lengths)
|
| 321 |
+
|
| 322 |
+
split_generator.split_info.num_examples = total_num_examples
|
| 323 |
+
split_generator.split_info.num_bytes = total_num_bytes
|
| 324 |
+
|
| 325 |
+
# should rename everything at the end
|
| 326 |
+
logger.debug(f"Renaming {total_shards} shards.")
|
| 327 |
+
if total_shards > 1:
|
| 328 |
+
split_generator.split_info.shard_lengths = all_shard_lengths
|
| 329 |
+
|
| 330 |
+
# Define fs outside of _rename_shard so that we don't reference self in the function, which will result in a
|
| 331 |
+
# pickling error due to pickling the SparkContext.
|
| 332 |
+
fs = self._fs
|
| 333 |
+
|
| 334 |
+
# use the -SSSSS-of-NNNNN pattern
|
| 335 |
+
def _rename_shard(
|
| 336 |
+
task_id: int,
|
| 337 |
+
shard_id: int,
|
| 338 |
+
global_shard_id: int,
|
| 339 |
+
):
|
| 340 |
+
rename(
|
| 341 |
+
fs,
|
| 342 |
+
fpath.replace("SSSSS", f"{shard_id:05d}").replace("TTTTT", f"{task_id:05d}"),
|
| 343 |
+
fpath.replace("TTTTT-SSSSS", f"{global_shard_id:05d}").replace("NNNNN", f"{total_shards:05d}"),
|
| 344 |
+
)
|
| 345 |
+
|
| 346 |
+
args = []
|
| 347 |
+
global_shard_id = 0
|
| 348 |
+
for i in range(len(task_id_and_num_shards)):
|
| 349 |
+
task_id, num_shards = task_id_and_num_shards[i]
|
| 350 |
+
for shard_id in range(num_shards):
|
| 351 |
+
args.append([task_id, shard_id, global_shard_id])
|
| 352 |
+
global_shard_id += 1
|
| 353 |
+
self._spark.sparkContext.parallelize(args, len(args)).map(lambda args: _rename_shard(*args)).collect()
|
| 354 |
+
else:
|
| 355 |
+
# don't use any pattern
|
| 356 |
+
shard_id = 0
|
| 357 |
+
task_id = task_id_and_num_shards[0][0]
|
| 358 |
+
self._rename(
|
| 359 |
+
fpath.replace("SSSSS", f"{shard_id:05d}").replace("TTTTT", f"{task_id:05d}"),
|
| 360 |
+
fpath.replace(SUFFIX, ""),
|
| 361 |
+
)
|
| 362 |
+
|
| 363 |
+
def _get_examples_iterable_for_split(
|
| 364 |
+
self,
|
| 365 |
+
split_generator: "datasets.SplitGenerator",
|
| 366 |
+
) -> SparkExamplesIterable:
|
| 367 |
+
return SparkExamplesIterable(self.df)
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/text/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/text/text.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from dataclasses import dataclass
|
| 2 |
+
from io import StringIO
|
| 3 |
+
from typing import Literal, Optional
|
| 4 |
+
|
| 5 |
+
import pyarrow as pa
|
| 6 |
+
|
| 7 |
+
import datasets
|
| 8 |
+
from datasets.builder import Key
|
| 9 |
+
from datasets.features.features import require_storage_cast
|
| 10 |
+
from datasets.table import table_cast
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
@dataclass
|
| 17 |
+
class TextConfig(datasets.BuilderConfig):
|
| 18 |
+
"""BuilderConfig for text files.
|
| 19 |
+
|
| 20 |
+
Args:
|
| 21 |
+
features: (`Features`, *optional*):
|
| 22 |
+
Cast the data to `features`.
|
| 23 |
+
encoding: (`str`, defaults to "utf-8"):
|
| 24 |
+
Encoding to decode the file.
|
| 25 |
+
encoding_errors: (`str`, *optional*):
|
| 26 |
+
Argument to define what to do in case of encoding error.
|
| 27 |
+
This is the same as the `error` argument in `open()`.
|
| 28 |
+
chunksize: (`Features`, *optional*, defaults to "10MB"):
|
| 29 |
+
Chunk size to read the data.
|
| 30 |
+
keep_linebreaks: (`bool`, defaults to False):
|
| 31 |
+
Whether to keep line breaks.
|
| 32 |
+
sample_by (`Literal["line", "paragraph", "document"]`, defaults to "line"):
|
| 33 |
+
Whether to load data per line, praragraph or document.
|
| 34 |
+
By default one row in the dataset = one line.
|
| 35 |
+
"""
|
| 36 |
+
|
| 37 |
+
features: Optional[datasets.Features] = None
|
| 38 |
+
encoding: str = "utf-8"
|
| 39 |
+
encoding_errors: Optional[str] = None
|
| 40 |
+
chunksize: int = 10 << 20 # 10MB
|
| 41 |
+
keep_linebreaks: bool = False
|
| 42 |
+
sample_by: Literal["line", "paragraph", "document"] = "line"
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class Text(datasets.ArrowBasedBuilder):
|
| 46 |
+
BUILDER_CONFIG_CLASS = TextConfig
|
| 47 |
+
|
| 48 |
+
def _info(self):
|
| 49 |
+
return datasets.DatasetInfo(features=self.config.features)
|
| 50 |
+
|
| 51 |
+
def _split_generators(self, dl_manager):
|
| 52 |
+
"""The `data_files` kwarg in load_dataset() can be a str, List[str], Dict[str,str], or Dict[str,List[str]].
|
| 53 |
+
|
| 54 |
+
If str or List[str], then the dataset returns only the 'train' split.
|
| 55 |
+
If dict, then keys should be from the `datasets.Split` enum.
|
| 56 |
+
"""
|
| 57 |
+
if not self.config.data_files:
|
| 58 |
+
raise ValueError(f"At least one data file must be specified, but got data_files={self.config.data_files}")
|
| 59 |
+
dl_manager.download_config.extract_on_the_fly = True
|
| 60 |
+
base_data_files = dl_manager.download(self.config.data_files)
|
| 61 |
+
extracted_data_files = dl_manager.extract(base_data_files)
|
| 62 |
+
splits = []
|
| 63 |
+
for split_name, files in extracted_data_files.items():
|
| 64 |
+
files_iterables = [dl_manager.iter_files(file) for file in files]
|
| 65 |
+
splits.append(
|
| 66 |
+
datasets.SplitGenerator(
|
| 67 |
+
name=split_name,
|
| 68 |
+
gen_kwargs={"files_iterables": files_iterables, "base_files": base_data_files[split_name]},
|
| 69 |
+
)
|
| 70 |
+
)
|
| 71 |
+
return splits
|
| 72 |
+
|
| 73 |
+
def _cast_table(self, pa_table: pa.Table) -> pa.Table:
|
| 74 |
+
if self.config.features is not None:
|
| 75 |
+
schema = self.config.features.arrow_schema
|
| 76 |
+
if all(not require_storage_cast(feature) for feature in self.config.features.values()):
|
| 77 |
+
# cheaper cast
|
| 78 |
+
pa_table = pa_table.cast(schema)
|
| 79 |
+
else:
|
| 80 |
+
# more expensive cast; allows str <-> int/float or str to Audio for example
|
| 81 |
+
pa_table = table_cast(pa_table, schema)
|
| 82 |
+
return pa_table
|
| 83 |
+
else:
|
| 84 |
+
return pa_table.cast(pa.schema({"text": pa.string()}))
|
| 85 |
+
|
| 86 |
+
def _generate_shards(self, base_files, files_iterables):
|
| 87 |
+
yield from base_files
|
| 88 |
+
|
| 89 |
+
def _generate_tables(self, base_files, files_iterables):
|
| 90 |
+
pa_table_names = list(self.config.features) if self.config.features is not None else ["text"]
|
| 91 |
+
for shard_idx, files_iterable in enumerate(files_iterables):
|
| 92 |
+
for file in files_iterable:
|
| 93 |
+
# open in text mode, by default translates universal newlines ("\n", "\r\n" and "\r") into "\n"
|
| 94 |
+
with open(file, encoding=self.config.encoding, errors=self.config.encoding_errors) as f:
|
| 95 |
+
if self.config.sample_by == "line":
|
| 96 |
+
batch_idx = 0
|
| 97 |
+
while True:
|
| 98 |
+
batch = f.read(self.config.chunksize)
|
| 99 |
+
if not batch:
|
| 100 |
+
break
|
| 101 |
+
batch += f.readline() # finish current line
|
| 102 |
+
# StringIO.readlines, by default splits only on "\n" (and keeps line breaks)
|
| 103 |
+
batch = StringIO(batch).readlines()
|
| 104 |
+
if not self.config.keep_linebreaks:
|
| 105 |
+
batch = [line.rstrip("\n") for line in batch]
|
| 106 |
+
pa_table = pa.Table.from_arrays([pa.array(batch)], names=pa_table_names)
|
| 107 |
+
# Uncomment for debugging (will print the Arrow table size and elements)
|
| 108 |
+
# logger.warning(f"pa_table: {pa_table} num rows: {pa_table.num_rows}")
|
| 109 |
+
# logger.warning('\n'.join(str(pa_table.slice(i, 1).to_pydict()) for i in range(pa_table.num_rows)))
|
| 110 |
+
yield Key(shard_idx, batch_idx), self._cast_table(pa_table)
|
| 111 |
+
batch_idx += 1
|
| 112 |
+
elif self.config.sample_by == "paragraph":
|
| 113 |
+
batch_idx = 0
|
| 114 |
+
batch = ""
|
| 115 |
+
while True:
|
| 116 |
+
new_batch = f.read(self.config.chunksize)
|
| 117 |
+
if not new_batch:
|
| 118 |
+
break
|
| 119 |
+
batch += new_batch
|
| 120 |
+
batch += f.readline() # finish current line
|
| 121 |
+
batch = batch.split("\n\n")
|
| 122 |
+
pa_table = pa.Table.from_arrays(
|
| 123 |
+
[pa.array([example for example in batch[:-1] if example])], names=pa_table_names
|
| 124 |
+
)
|
| 125 |
+
# Uncomment for debugging (will print the Arrow table size and elements)
|
| 126 |
+
# logger.warning(f"pa_table: {pa_table} num rows: {pa_table.num_rows}")
|
| 127 |
+
# logger.warning('\n'.join(str(pa_table.slice(i, 1).to_pydict()) for i in range(pa_table.num_rows)))
|
| 128 |
+
yield Key(shard_idx, batch_idx), self._cast_table(pa_table)
|
| 129 |
+
batch_idx += 1
|
| 130 |
+
batch = batch[-1]
|
| 131 |
+
if batch:
|
| 132 |
+
pa_table = pa.Table.from_arrays([pa.array([batch])], names=pa_table_names)
|
| 133 |
+
yield (shard_idx, batch_idx), self._cast_table(pa_table)
|
| 134 |
+
elif self.config.sample_by == "document":
|
| 135 |
+
text = f.read()
|
| 136 |
+
pa_table = pa.Table.from_arrays([pa.array([text])], names=pa_table_names)
|
| 137 |
+
yield Key(shard_idx, 0), self._cast_table(pa_table)
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/webdataset/__init__.py
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/webdataset/_tenbin.py
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#
|
| 2 |
+
# Copyright (c) 2017-2021 NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
# This file coems from the WebDataset library.
|
| 4 |
+
# See the LICENSE file for licensing terms (BSD-style).
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
Binary tensor encodings for PyTorch and NumPy.
|
| 9 |
+
|
| 10 |
+
This defines efficient binary encodings for tensors. The format is 8 byte
|
| 11 |
+
aligned and can be used directly for computations when transmitted, say,
|
| 12 |
+
via RDMA. The format is supported by WebDataset with the `.ten` filename
|
| 13 |
+
extension. It is also used by Tensorcom, Tensorcom RDMA, and can be used
|
| 14 |
+
for fast tensor storage with LMDB and in disk files (which can be memory
|
| 15 |
+
mapped)
|
| 16 |
+
|
| 17 |
+
Data is encoded as a series of chunks:
|
| 18 |
+
|
| 19 |
+
- magic number (int64)
|
| 20 |
+
- length in bytes (int64)
|
| 21 |
+
- bytes (multiple of 64 bytes long)
|
| 22 |
+
|
| 23 |
+
Arrays are a header chunk followed by a data chunk.
|
| 24 |
+
Header chunks have the following structure:
|
| 25 |
+
|
| 26 |
+
- dtype (int64)
|
| 27 |
+
- 8 byte array name
|
| 28 |
+
- ndim (int64)
|
| 29 |
+
- dim[0]
|
| 30 |
+
- dim[1]
|
| 31 |
+
- ...
|
| 32 |
+
"""
|
| 33 |
+
|
| 34 |
+
import struct
|
| 35 |
+
import sys
|
| 36 |
+
|
| 37 |
+
import numpy as np
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def bytelen(a):
|
| 41 |
+
"""Determine the length of a in bytes."""
|
| 42 |
+
if hasattr(a, "nbytes"):
|
| 43 |
+
return a.nbytes
|
| 44 |
+
elif isinstance(a, (bytearray, bytes)):
|
| 45 |
+
return len(a)
|
| 46 |
+
else:
|
| 47 |
+
raise ValueError(a, "cannot determine nbytes")
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def bytedata(a):
|
| 51 |
+
"""Return a the raw data corresponding to a."""
|
| 52 |
+
if isinstance(a, (bytearray, bytes, memoryview)):
|
| 53 |
+
return a
|
| 54 |
+
elif hasattr(a, "data"):
|
| 55 |
+
return a.data
|
| 56 |
+
else:
|
| 57 |
+
raise ValueError(a, "cannot return bytedata")
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
# tables for converting between long/short NumPy dtypes
|
| 61 |
+
|
| 62 |
+
long_to_short = """
|
| 63 |
+
float16 f2
|
| 64 |
+
float32 f4
|
| 65 |
+
float64 f8
|
| 66 |
+
int8 i1
|
| 67 |
+
int16 i2
|
| 68 |
+
int32 i4
|
| 69 |
+
int64 i8
|
| 70 |
+
uint8 u1
|
| 71 |
+
uint16 u2
|
| 72 |
+
unit32 u4
|
| 73 |
+
uint64 u8
|
| 74 |
+
""".strip()
|
| 75 |
+
long_to_short = [x.split() for x in long_to_short.split("\n")]
|
| 76 |
+
long_to_short = {x[0]: x[1] for x in long_to_short}
|
| 77 |
+
short_to_long = {v: k for k, v in long_to_short.items()}
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def check_acceptable_input_type(data, allow64):
|
| 81 |
+
"""Check that the data has an acceptable type for tensor encoding.
|
| 82 |
+
|
| 83 |
+
:param data: array
|
| 84 |
+
:param allow64: allow 64 bit types
|
| 85 |
+
"""
|
| 86 |
+
for a in data:
|
| 87 |
+
if a.dtype.name not in long_to_short:
|
| 88 |
+
raise ValueError("unsupported dataypte")
|
| 89 |
+
if not allow64 and a.dtype.name not in ["float64", "int64", "uint64"]:
|
| 90 |
+
raise ValueError("64 bit datatypes not allowed unless explicitly enabled")
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def str64(s):
|
| 94 |
+
"""Convert a string to an int64."""
|
| 95 |
+
s = s + "\0" * (8 - len(s))
|
| 96 |
+
s = s.encode("ascii")
|
| 97 |
+
return struct.unpack("@q", s)[0]
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def unstr64(i):
|
| 101 |
+
"""Convert an int64 to a string."""
|
| 102 |
+
b = struct.pack("@q", i)
|
| 103 |
+
return b.decode("ascii").strip("\0")
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
def check_infos(data, infos, required_infos=None):
|
| 107 |
+
"""Verify the info strings."""
|
| 108 |
+
if required_infos is False or required_infos is None:
|
| 109 |
+
return data
|
| 110 |
+
if required_infos is True:
|
| 111 |
+
return data, infos
|
| 112 |
+
if not isinstance(required_infos, (tuple, list)):
|
| 113 |
+
raise ValueError("required_infos must be tuple or list")
|
| 114 |
+
for required, actual in zip(required_infos, infos):
|
| 115 |
+
raise ValueError(f"actual info {actual} doesn't match required info {required}")
|
| 116 |
+
return data
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def encode_header(a, info=""):
|
| 120 |
+
"""Encode an array header as a byte array."""
|
| 121 |
+
if a.ndim >= 10:
|
| 122 |
+
raise ValueError("too many dimensions")
|
| 123 |
+
if a.nbytes != np.prod(a.shape) * a.itemsize:
|
| 124 |
+
raise ValueError("mismatch between size and shape")
|
| 125 |
+
if a.dtype.name not in long_to_short:
|
| 126 |
+
raise ValueError("unsupported array type")
|
| 127 |
+
header = [str64(long_to_short[a.dtype.name]), str64(info), len(a.shape)] + list(a.shape)
|
| 128 |
+
return bytedata(np.array(header, dtype="i8"))
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
def decode_header(h):
|
| 132 |
+
"""Decode a byte array into an array header."""
|
| 133 |
+
h = np.frombuffer(h, dtype="i8")
|
| 134 |
+
if unstr64(h[0]) not in short_to_long:
|
| 135 |
+
raise ValueError("unsupported array type")
|
| 136 |
+
dtype = np.dtype(short_to_long[unstr64(h[0])])
|
| 137 |
+
info = unstr64(h[1])
|
| 138 |
+
rank = int(h[2])
|
| 139 |
+
shape = tuple(h[3 : 3 + rank])
|
| 140 |
+
return shape, dtype, info
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
def encode_list(l, infos=None): # noqa: E741
|
| 144 |
+
"""Given a list of arrays, encode them into a list of byte arrays."""
|
| 145 |
+
if infos is None:
|
| 146 |
+
infos = [""]
|
| 147 |
+
else:
|
| 148 |
+
if len(l) != len(infos):
|
| 149 |
+
raise ValueError(f"length of list {l} must muatch length of infos {infos}")
|
| 150 |
+
result = []
|
| 151 |
+
for i, a in enumerate(l):
|
| 152 |
+
header = encode_header(a, infos[i % len(infos)])
|
| 153 |
+
result += [header, bytedata(a)]
|
| 154 |
+
return result
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def decode_list(l, infos=False): # noqa: E741
|
| 158 |
+
"""Given a list of byte arrays, decode them into arrays."""
|
| 159 |
+
result = []
|
| 160 |
+
infos0 = []
|
| 161 |
+
for header, data in zip(l[::2], l[1::2]):
|
| 162 |
+
shape, dtype, info = decode_header(header)
|
| 163 |
+
a = np.frombuffer(data, dtype=dtype, count=np.prod(shape)).reshape(*shape)
|
| 164 |
+
result += [a]
|
| 165 |
+
infos0 += [info]
|
| 166 |
+
return check_infos(result, infos0, infos)
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
magic_str = "~TenBin~"
|
| 170 |
+
magic = str64(magic_str)
|
| 171 |
+
magic_bytes = unstr64(magic).encode("ascii")
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
def roundup(n, k=64):
|
| 175 |
+
"""Round up to the next multiple of 64."""
|
| 176 |
+
return k * ((n + k - 1) // k)
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
def encode_chunks(l): # noqa: E741
|
| 180 |
+
"""Encode a list of chunks into a single byte array, with lengths and magics.."""
|
| 181 |
+
size = sum(16 + roundup(b.nbytes) for b in l)
|
| 182 |
+
result = bytearray(size)
|
| 183 |
+
offset = 0
|
| 184 |
+
for b in l:
|
| 185 |
+
result[offset : offset + 8] = magic_bytes
|
| 186 |
+
offset += 8
|
| 187 |
+
result[offset : offset + 8] = struct.pack("@q", b.nbytes)
|
| 188 |
+
offset += 8
|
| 189 |
+
result[offset : offset + bytelen(b)] = b
|
| 190 |
+
offset += roundup(bytelen(b))
|
| 191 |
+
return result
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
def decode_chunks(buf):
|
| 195 |
+
"""Decode a byte array into a list of chunks."""
|
| 196 |
+
result = []
|
| 197 |
+
offset = 0
|
| 198 |
+
total = bytelen(buf)
|
| 199 |
+
while offset < total:
|
| 200 |
+
if magic_bytes != buf[offset : offset + 8]:
|
| 201 |
+
raise ValueError("magic bytes mismatch")
|
| 202 |
+
offset += 8
|
| 203 |
+
nbytes = struct.unpack("@q", buf[offset : offset + 8])[0]
|
| 204 |
+
offset += 8
|
| 205 |
+
b = buf[offset : offset + nbytes]
|
| 206 |
+
offset += roundup(nbytes)
|
| 207 |
+
result.append(b)
|
| 208 |
+
return result
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
def encode_buffer(l, infos=None): # noqa: E741
|
| 212 |
+
"""Encode a list of arrays into a single byte array."""
|
| 213 |
+
if not isinstance(l, list):
|
| 214 |
+
raise ValueError("requires list")
|
| 215 |
+
return encode_chunks(encode_list(l, infos=infos))
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
def decode_buffer(buf, infos=False):
|
| 219 |
+
"""Decode a byte array into a list of arrays."""
|
| 220 |
+
return decode_list(decode_chunks(buf), infos=infos)
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
def write_chunk(stream, buf):
|
| 224 |
+
"""Write a byte chunk to the stream with magics, length, and padding."""
|
| 225 |
+
nbytes = bytelen(buf)
|
| 226 |
+
stream.write(magic_bytes)
|
| 227 |
+
stream.write(struct.pack("@q", nbytes))
|
| 228 |
+
stream.write(bytedata(buf))
|
| 229 |
+
padding = roundup(nbytes) - nbytes
|
| 230 |
+
if padding > 0:
|
| 231 |
+
stream.write(b"\0" * padding)
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
def read_chunk(stream):
|
| 235 |
+
"""Read a byte chunk from a stream with magics, length, and padding."""
|
| 236 |
+
magic = stream.read(8)
|
| 237 |
+
if magic == b"":
|
| 238 |
+
return None
|
| 239 |
+
if magic != magic_bytes:
|
| 240 |
+
raise ValueError("magic number does not match")
|
| 241 |
+
nbytes = stream.read(8)
|
| 242 |
+
nbytes = struct.unpack("@q", nbytes)[0]
|
| 243 |
+
if nbytes < 0:
|
| 244 |
+
raise ValueError("negative nbytes")
|
| 245 |
+
data = stream.read(nbytes)
|
| 246 |
+
padding = roundup(nbytes) - nbytes
|
| 247 |
+
if padding > 0:
|
| 248 |
+
stream.read(padding)
|
| 249 |
+
return data
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
def write(stream, l, infos=None): # noqa: E741
|
| 253 |
+
"""Write a list of arrays to a stream, with magics, length, and padding."""
|
| 254 |
+
for chunk in encode_list(l, infos=infos):
|
| 255 |
+
write_chunk(stream, chunk)
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
def read(stream, n=sys.maxsize, infos=False):
|
| 259 |
+
"""Read a list of arrays from a stream, with magics, length, and padding."""
|
| 260 |
+
chunks = []
|
| 261 |
+
for _ in range(n):
|
| 262 |
+
header = read_chunk(stream)
|
| 263 |
+
if header is None:
|
| 264 |
+
break
|
| 265 |
+
data = read_chunk(stream)
|
| 266 |
+
if data is None:
|
| 267 |
+
raise ValueError("premature EOF")
|
| 268 |
+
chunks += [header, data]
|
| 269 |
+
return decode_list(chunks, infos=infos)
|
| 270 |
+
|
| 271 |
+
|
| 272 |
+
def save(fname, *args, infos=None, nocheck=False):
|
| 273 |
+
"""Save a list of arrays to a file, with magics, length, and padding."""
|
| 274 |
+
if not nocheck and not fname.endswith(".ten"):
|
| 275 |
+
raise ValueError("file name should end in .ten")
|
| 276 |
+
with open(fname, "wb") as stream:
|
| 277 |
+
write(stream, args, infos=infos)
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
def load(fname, infos=False, nocheck=False):
|
| 281 |
+
"""Read a list of arrays from a file, with magics, length, and padding."""
|
| 282 |
+
if not nocheck and not fname.endswith(".ten"):
|
| 283 |
+
raise ValueError("file name should end in .ten")
|
| 284 |
+
with open(fname, "rb") as stream:
|
| 285 |
+
return read(stream, infos=infos)
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/webdataset/webdataset.py
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import json
|
| 3 |
+
import re
|
| 4 |
+
from itertools import islice
|
| 5 |
+
from typing import Any, Callable
|
| 6 |
+
|
| 7 |
+
import fsspec
|
| 8 |
+
import numpy as np
|
| 9 |
+
import pyarrow as pa
|
| 10 |
+
|
| 11 |
+
import datasets
|
| 12 |
+
from datasets.builder import Key
|
| 13 |
+
from datasets.features.features import cast_to_python_objects
|
| 14 |
+
from datasets.utils.file_utils import SINGLE_FILE_COMPRESSION_EXTENSION_TO_PROTOCOL, xbasename
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
logger = datasets.utils.logging.get_logger(__name__)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class WebDataset(datasets.GeneratorBasedBuilder):
|
| 21 |
+
DEFAULT_WRITER_BATCH_SIZE = 100
|
| 22 |
+
IMAGE_EXTENSIONS: list[str] # definition at the bottom of the script
|
| 23 |
+
AUDIO_EXTENSIONS: list[str] # definition at the bottom of the script
|
| 24 |
+
VIDEO_EXTENSIONS: list[str] # definition at the bottom of the script
|
| 25 |
+
DECODERS: dict[str, Callable[[Any], Any]] # definition at the bottom of the script
|
| 26 |
+
NUM_EXAMPLES_FOR_FEATURES_INFERENCE = 5
|
| 27 |
+
|
| 28 |
+
@classmethod
|
| 29 |
+
def _get_pipeline_from_tar(cls, tar_path, tar_iterator):
|
| 30 |
+
current_example = {}
|
| 31 |
+
fs: fsspec.AbstractFileSystem = fsspec.filesystem("memory")
|
| 32 |
+
streaming_download_manager = datasets.StreamingDownloadManager()
|
| 33 |
+
for filename, f in tar_iterator:
|
| 34 |
+
example_key, field_name = base_plus_ext(filename)
|
| 35 |
+
if example_key is None:
|
| 36 |
+
continue
|
| 37 |
+
if current_example and current_example["__key__"] != example_key:
|
| 38 |
+
# reposition some keys in last position
|
| 39 |
+
current_example["__key__"] = current_example.pop("__key__")
|
| 40 |
+
current_example["__url__"] = current_example.pop("__url__")
|
| 41 |
+
yield current_example
|
| 42 |
+
current_example = {}
|
| 43 |
+
current_example["__key__"] = example_key
|
| 44 |
+
current_example["__url__"] = tar_path
|
| 45 |
+
current_example[field_name] = f.read()
|
| 46 |
+
if field_name.split(".")[-1].lower() in SINGLE_FILE_COMPRESSION_EXTENSION_TO_PROTOCOL:
|
| 47 |
+
fs.write_bytes(filename, current_example[field_name])
|
| 48 |
+
extracted_file_path = streaming_download_manager.extract(f"memory://{filename}")
|
| 49 |
+
with fsspec.open(extracted_file_path) as f:
|
| 50 |
+
current_example[field_name] = f.read()
|
| 51 |
+
fs.delete(filename)
|
| 52 |
+
data_extension = xbasename(extracted_file_path).split(".")[-1].lower()
|
| 53 |
+
else:
|
| 54 |
+
data_extension = field_name.split(".")[-1].lower()
|
| 55 |
+
if data_extension in cls.DECODERS:
|
| 56 |
+
current_example[field_name] = cls.DECODERS[data_extension](current_example[field_name])
|
| 57 |
+
if current_example:
|
| 58 |
+
yield current_example
|
| 59 |
+
|
| 60 |
+
def _info(self) -> datasets.DatasetInfo:
|
| 61 |
+
return datasets.DatasetInfo()
|
| 62 |
+
|
| 63 |
+
def _split_generators(self, dl_manager):
|
| 64 |
+
"""We handle string, list and dicts in datafiles"""
|
| 65 |
+
# Download the data files
|
| 66 |
+
if not self.config.data_files:
|
| 67 |
+
raise ValueError(f"At least one data file must be specified, but got data_files={self.config.data_files}")
|
| 68 |
+
data_files = dl_manager.download(self.config.data_files)
|
| 69 |
+
splits = []
|
| 70 |
+
for split_name, tar_paths in data_files.items():
|
| 71 |
+
tar_iterators = [dl_manager.iter_archive(tar_path) for tar_path in tar_paths]
|
| 72 |
+
splits.append(
|
| 73 |
+
datasets.SplitGenerator(
|
| 74 |
+
name=split_name, gen_kwargs={"tar_paths": tar_paths, "tar_iterators": tar_iterators}
|
| 75 |
+
)
|
| 76 |
+
)
|
| 77 |
+
if not self.info.features:
|
| 78 |
+
# Get one example to get the feature types
|
| 79 |
+
pipeline = self._get_pipeline_from_tar(tar_paths[0], tar_iterators[0])
|
| 80 |
+
first_examples = list(islice(pipeline, self.NUM_EXAMPLES_FOR_FEATURES_INFERENCE))
|
| 81 |
+
if any(example.keys() != first_examples[0].keys() for example in first_examples):
|
| 82 |
+
raise ValueError(
|
| 83 |
+
"The TAR archives of the dataset should be in WebDataset format, "
|
| 84 |
+
"but the files in the archive don't share the same prefix or the same types."
|
| 85 |
+
)
|
| 86 |
+
pa_tables = [
|
| 87 |
+
pa.Table.from_pylist(cast_to_python_objects([example], only_1d_for_numpy=True))
|
| 88 |
+
for example in first_examples
|
| 89 |
+
]
|
| 90 |
+
inferred_arrow_schema = pa.concat_tables(pa_tables, promote_options="default").schema
|
| 91 |
+
features = datasets.Features.from_arrow_schema(inferred_arrow_schema)
|
| 92 |
+
|
| 93 |
+
for field_name in first_examples[0]:
|
| 94 |
+
extension = field_name.rsplit(".", 1)[-1].lower()
|
| 95 |
+
# Set Image types
|
| 96 |
+
if extension in self.IMAGE_EXTENSIONS:
|
| 97 |
+
features[field_name] = datasets.Image()
|
| 98 |
+
# Set Audio types
|
| 99 |
+
if extension in self.AUDIO_EXTENSIONS:
|
| 100 |
+
features[field_name] = datasets.Audio()
|
| 101 |
+
# Set Video types
|
| 102 |
+
if extension in self.VIDEO_EXTENSIONS:
|
| 103 |
+
features[field_name] = datasets.Video()
|
| 104 |
+
self.info.features = features
|
| 105 |
+
|
| 106 |
+
return splits
|
| 107 |
+
|
| 108 |
+
def _generate_shards(self, tar_paths, tar_iterators):
|
| 109 |
+
yield from tar_paths
|
| 110 |
+
|
| 111 |
+
def _generate_examples(self, tar_paths, tar_iterators):
|
| 112 |
+
image_field_names = [
|
| 113 |
+
field_name for field_name, feature in self.info.features.items() if isinstance(feature, datasets.Image)
|
| 114 |
+
]
|
| 115 |
+
audio_field_names = [
|
| 116 |
+
field_name for field_name, feature in self.info.features.items() if isinstance(feature, datasets.Audio)
|
| 117 |
+
]
|
| 118 |
+
all_field_names = list(self.info.features.keys())
|
| 119 |
+
for tar_idx, (tar_path, tar_iterator) in enumerate(zip(tar_paths, tar_iterators)):
|
| 120 |
+
for example_idx, example in enumerate(self._get_pipeline_from_tar(tar_path, tar_iterator)):
|
| 121 |
+
for field_name in all_field_names:
|
| 122 |
+
if field_name not in example:
|
| 123 |
+
example[field_name] = None
|
| 124 |
+
for field_name in image_field_names + audio_field_names:
|
| 125 |
+
if example[field_name] is not None:
|
| 126 |
+
example[field_name] = {
|
| 127 |
+
"path": example["__key__"] + "." + field_name,
|
| 128 |
+
"bytes": example[field_name],
|
| 129 |
+
}
|
| 130 |
+
yield Key(tar_idx, example_idx), example
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
# Source: https://github.com/webdataset/webdataset/blob/87bd5aa41602d57f070f65a670893ee625702f2f/webdataset/tariterators.py#L25
|
| 134 |
+
def base_plus_ext(path):
|
| 135 |
+
"""Split off all file extensions.
|
| 136 |
+
|
| 137 |
+
Returns base, allext.
|
| 138 |
+
"""
|
| 139 |
+
match = re.match(r"^((?:.*/|)[^.]+)[.]([^/]*)$", path)
|
| 140 |
+
if not match:
|
| 141 |
+
return None, None
|
| 142 |
+
return match.group(1), match.group(2)
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
# Obtained with:
|
| 146 |
+
# ```
|
| 147 |
+
# import PIL.Image
|
| 148 |
+
# IMAGE_EXTENSIONS = []
|
| 149 |
+
# PIL.Image.init()
|
| 150 |
+
# for ext, format in PIL.Image.EXTENSION.items():
|
| 151 |
+
# if format in PIL.Image.OPEN:
|
| 152 |
+
# IMAGE_EXTENSIONS.append(ext[1:])
|
| 153 |
+
# ```
|
| 154 |
+
# We intentionally do not run this code on launch because:
|
| 155 |
+
# (1) Pillow is an optional dependency, so importing Pillow in global namespace is not allowed
|
| 156 |
+
# (2) To ensure the list of supported extensions is deterministic
|
| 157 |
+
IMAGE_EXTENSIONS = [
|
| 158 |
+
"blp",
|
| 159 |
+
"bmp",
|
| 160 |
+
"dib",
|
| 161 |
+
"bufr",
|
| 162 |
+
"cur",
|
| 163 |
+
"pcx",
|
| 164 |
+
"dcx",
|
| 165 |
+
"dds",
|
| 166 |
+
"ps",
|
| 167 |
+
"eps",
|
| 168 |
+
"fit",
|
| 169 |
+
"fits",
|
| 170 |
+
"fli",
|
| 171 |
+
"flc",
|
| 172 |
+
"ftc",
|
| 173 |
+
"ftu",
|
| 174 |
+
"gbr",
|
| 175 |
+
"gif",
|
| 176 |
+
"grib",
|
| 177 |
+
"h5",
|
| 178 |
+
"hdf",
|
| 179 |
+
"png",
|
| 180 |
+
"apng",
|
| 181 |
+
"jp2",
|
| 182 |
+
"j2k",
|
| 183 |
+
"jpc",
|
| 184 |
+
"jpf",
|
| 185 |
+
"jpx",
|
| 186 |
+
"j2c",
|
| 187 |
+
"icns",
|
| 188 |
+
"ico",
|
| 189 |
+
"im",
|
| 190 |
+
"iim",
|
| 191 |
+
"tif",
|
| 192 |
+
"tiff",
|
| 193 |
+
"jfif",
|
| 194 |
+
"jpe",
|
| 195 |
+
"jpg",
|
| 196 |
+
"jpeg",
|
| 197 |
+
"mpg",
|
| 198 |
+
"mpeg",
|
| 199 |
+
"msp",
|
| 200 |
+
"pcd",
|
| 201 |
+
"pxr",
|
| 202 |
+
"pbm",
|
| 203 |
+
"pgm",
|
| 204 |
+
"ppm",
|
| 205 |
+
"pnm",
|
| 206 |
+
"psd",
|
| 207 |
+
"bw",
|
| 208 |
+
"rgb",
|
| 209 |
+
"rgba",
|
| 210 |
+
"sgi",
|
| 211 |
+
"ras",
|
| 212 |
+
"tga",
|
| 213 |
+
"icb",
|
| 214 |
+
"vda",
|
| 215 |
+
"vst",
|
| 216 |
+
"webp",
|
| 217 |
+
"wmf",
|
| 218 |
+
"emf",
|
| 219 |
+
"xbm",
|
| 220 |
+
"xpm",
|
| 221 |
+
]
|
| 222 |
+
WebDataset.IMAGE_EXTENSIONS = IMAGE_EXTENSIONS
|
| 223 |
+
|
| 224 |
+
|
| 225 |
+
# Obtained with:
|
| 226 |
+
# ```
|
| 227 |
+
# import soundfile as sf
|
| 228 |
+
#
|
| 229 |
+
# AUDIO_EXTENSIONS = [f".{format.lower()}" for format in sf.available_formats().keys()]
|
| 230 |
+
#
|
| 231 |
+
# # .opus decoding is supported if libsndfile >= 1.0.31:
|
| 232 |
+
# AUDIO_EXTENSIONS.extend([".mp3", ".opus"])
|
| 233 |
+
# ```
|
| 234 |
+
# We intentionally did not run this code on launch because:
|
| 235 |
+
# (1) Soundfile was an optional dependency, so importing it in global namespace is not allowed
|
| 236 |
+
# (2) To ensure the list of supported extensions is deterministic
|
| 237 |
+
# (3) We use TorchCodec now anyways instead of Soundfile
|
| 238 |
+
AUDIO_EXTENSIONS = [
|
| 239 |
+
"aiff",
|
| 240 |
+
"au",
|
| 241 |
+
"avr",
|
| 242 |
+
"caf",
|
| 243 |
+
"flac",
|
| 244 |
+
"htk",
|
| 245 |
+
"svx",
|
| 246 |
+
"mat4",
|
| 247 |
+
"mat5",
|
| 248 |
+
"mpc2k",
|
| 249 |
+
"ogg",
|
| 250 |
+
"paf",
|
| 251 |
+
"pvf",
|
| 252 |
+
"raw",
|
| 253 |
+
"rf64",
|
| 254 |
+
"sd2",
|
| 255 |
+
"sds",
|
| 256 |
+
"ircam",
|
| 257 |
+
"voc",
|
| 258 |
+
"w64",
|
| 259 |
+
"wav",
|
| 260 |
+
"nist",
|
| 261 |
+
"wavex",
|
| 262 |
+
"wve",
|
| 263 |
+
"xi",
|
| 264 |
+
"mp3",
|
| 265 |
+
"opus",
|
| 266 |
+
]
|
| 267 |
+
WebDataset.AUDIO_EXTENSIONS = AUDIO_EXTENSIONS
|
| 268 |
+
|
| 269 |
+
|
| 270 |
+
# TODO: initial list, we should check the compatibility of other formats
|
| 271 |
+
VIDEO_EXTENSIONS = [
|
| 272 |
+
"mkv",
|
| 273 |
+
"mp4",
|
| 274 |
+
"avi",
|
| 275 |
+
"mpeg",
|
| 276 |
+
"mov",
|
| 277 |
+
]
|
| 278 |
+
WebDataset.VIDEO_EXTENSIONS = VIDEO_EXTENSIONS
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
def text_loads(data: bytes):
|
| 282 |
+
return data.decode("utf-8")
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
def tenbin_loads(data: bytes):
|
| 286 |
+
from . import _tenbin
|
| 287 |
+
|
| 288 |
+
return _tenbin.decode_buffer(data)
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
def msgpack_loads(data: bytes):
|
| 292 |
+
import msgpack
|
| 293 |
+
|
| 294 |
+
return msgpack.unpackb(data)
|
| 295 |
+
|
| 296 |
+
|
| 297 |
+
def npy_loads(data: bytes):
|
| 298 |
+
import numpy.lib.format
|
| 299 |
+
|
| 300 |
+
stream = io.BytesIO(data)
|
| 301 |
+
return numpy.lib.format.read_array(stream, allow_pickle=False)
|
| 302 |
+
|
| 303 |
+
|
| 304 |
+
def npz_loads(data: bytes):
|
| 305 |
+
return np.load(io.BytesIO(data), allow_pickle=False)
|
| 306 |
+
|
| 307 |
+
|
| 308 |
+
def cbor_loads(data: bytes):
|
| 309 |
+
import cbor
|
| 310 |
+
|
| 311 |
+
return cbor.loads(data)
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
def torch_loads(data: bytes):
|
| 315 |
+
import torch
|
| 316 |
+
|
| 317 |
+
return torch.load(io.BytesIO(data), weights_only=True)
|
| 318 |
+
|
| 319 |
+
|
| 320 |
+
# Obtained by checking `decoders` in `webdataset.autodecode`
|
| 321 |
+
# and removing unsafe extension decoders.
|
| 322 |
+
# Removed Pickle decoders:
|
| 323 |
+
# - "pyd": lambda data: pickle.loads(data)
|
| 324 |
+
# - "pickle": lambda data: pickle.loads(data)
|
| 325 |
+
# Modified NumPy decoders to fix CVE-2019-6446 (add allow_pickle=False and weights_only=True):
|
| 326 |
+
# - "npy": npy_loads,
|
| 327 |
+
# - "npz": lambda data: np.load(io.BytesIO(data)),
|
| 328 |
+
# - "pth": lambda data: torch_loads(data)
|
| 329 |
+
DECODERS = {
|
| 330 |
+
"txt": text_loads,
|
| 331 |
+
"text": text_loads,
|
| 332 |
+
"transcript": text_loads,
|
| 333 |
+
"cls": int,
|
| 334 |
+
"cls2": int,
|
| 335 |
+
"index": int,
|
| 336 |
+
"inx": int,
|
| 337 |
+
"id": int,
|
| 338 |
+
"json": json.loads,
|
| 339 |
+
"jsn": json.loads,
|
| 340 |
+
"ten": tenbin_loads,
|
| 341 |
+
"tb": tenbin_loads,
|
| 342 |
+
"mp": msgpack_loads,
|
| 343 |
+
"msg": msgpack_loads,
|
| 344 |
+
"npy": npy_loads,
|
| 345 |
+
"npz": npz_loads,
|
| 346 |
+
"cbor": cbor_loads,
|
| 347 |
+
"pth": torch_loads,
|
| 348 |
+
}
|
| 349 |
+
WebDataset.DECODERS = DECODERS
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/parallel/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
from .parallel import ParallelBackendConfig, parallel_backend, parallel_map
|
bioagent-bench/.venv/lib/python3.14/site-packages/datasets/parallel/parallel.py
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import contextlib
|
| 2 |
+
from multiprocessing import Pool, RLock
|
| 3 |
+
|
| 4 |
+
from tqdm.auto import tqdm
|
| 5 |
+
|
| 6 |
+
from ..utils import experimental, logging
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
logger = logging.get_logger(__name__)
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class ParallelBackendConfig:
|
| 13 |
+
backend_name = None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
@experimental
|
| 17 |
+
def parallel_map(function, iterable, num_proc, batched, batch_size, types, disable_tqdm, desc, single_map_nested_func):
|
| 18 |
+
"""
|
| 19 |
+
**Experimental.** Apply a function to iterable elements in parallel, where the implementation uses either
|
| 20 |
+
multiprocessing.Pool or joblib for parallelization.
|
| 21 |
+
|
| 22 |
+
Args:
|
| 23 |
+
function (`Callable[[Any], Any]`): Function to be applied to `iterable`.
|
| 24 |
+
iterable (`list`, `tuple` or `np.ndarray`): Iterable elements to apply function to.
|
| 25 |
+
num_proc (`int`): Number of processes (if no backend specified) or jobs (using joblib).
|
| 26 |
+
types (`tuple`): Additional types (besides `dict` values) to apply `function` recursively to their elements.
|
| 27 |
+
disable_tqdm (`bool`): Whether to disable the tqdm progressbar.
|
| 28 |
+
desc (`str`): Prefix for the tqdm progressbar.
|
| 29 |
+
single_map_nested_func (`Callable`): Map function that applies `function` to an element from `iterable`.
|
| 30 |
+
Takes a tuple of function, data_struct, types, rank, disable_tqdm, desc as input, where data_struct is an
|
| 31 |
+
element of `iterable`, and `rank` is used for progress bar.
|
| 32 |
+
"""
|
| 33 |
+
if ParallelBackendConfig.backend_name is None:
|
| 34 |
+
return _map_with_multiprocessing_pool(
|
| 35 |
+
function, iterable, num_proc, batched, batch_size, types, disable_tqdm, desc, single_map_nested_func
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
return _map_with_joblib(
|
| 39 |
+
function, iterable, num_proc, batched, batch_size, types, disable_tqdm, desc, single_map_nested_func
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def _map_with_multiprocessing_pool(
|
| 44 |
+
function, iterable, num_proc, batched, batch_size, types, disable_tqdm, desc, single_map_nested_func
|
| 45 |
+
):
|
| 46 |
+
num_proc = num_proc if num_proc <= len(iterable) else len(iterable)
|
| 47 |
+
split_kwds = [] # We organize the splits ourselve (contiguous splits)
|
| 48 |
+
for index in range(num_proc):
|
| 49 |
+
div = len(iterable) // num_proc
|
| 50 |
+
mod = len(iterable) % num_proc
|
| 51 |
+
start = div * index + min(index, mod)
|
| 52 |
+
end = start + div + (1 if index < mod else 0)
|
| 53 |
+
split_kwds.append((function, iterable[start:end], batched, batch_size, types, index, disable_tqdm, desc))
|
| 54 |
+
|
| 55 |
+
if len(iterable) != sum(len(i[1]) for i in split_kwds):
|
| 56 |
+
raise ValueError(
|
| 57 |
+
f"Error dividing inputs iterable among processes. "
|
| 58 |
+
f"Total number of objects {len(iterable)}, "
|
| 59 |
+
f"length: {sum(len(i[1]) for i in split_kwds)}"
|
| 60 |
+
)
|
| 61 |
+
|
| 62 |
+
logger.info(
|
| 63 |
+
f"Spawning {num_proc} processes for {len(iterable)} objects in slices of {[len(i[1]) for i in split_kwds]}"
|
| 64 |
+
)
|
| 65 |
+
initargs, initializer = None, None
|
| 66 |
+
if not disable_tqdm:
|
| 67 |
+
initargs, initializer = (RLock(),), tqdm.set_lock
|
| 68 |
+
with Pool(num_proc, initargs=initargs, initializer=initializer) as pool:
|
| 69 |
+
mapped = pool.map(single_map_nested_func, split_kwds)
|
| 70 |
+
logger.info(f"Finished {num_proc} processes")
|
| 71 |
+
mapped = [obj for proc_res in mapped for obj in proc_res]
|
| 72 |
+
logger.info(f"Unpacked {len(mapped)} objects")
|
| 73 |
+
|
| 74 |
+
return mapped
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def _map_with_joblib(
|
| 78 |
+
function, iterable, num_proc, batched, batch_size, types, disable_tqdm, desc, single_map_nested_func
|
| 79 |
+
):
|
| 80 |
+
# progress bar is not yet supported for _map_with_joblib, because tqdm couldn't accurately be applied to joblib,
|
| 81 |
+
# and it requires monkey-patching joblib internal classes which is subject to change
|
| 82 |
+
import joblib
|
| 83 |
+
|
| 84 |
+
with joblib.parallel_backend(ParallelBackendConfig.backend_name, n_jobs=num_proc):
|
| 85 |
+
return joblib.Parallel()(
|
| 86 |
+
joblib.delayed(single_map_nested_func)((function, obj, batched, batch_size, types, None, True, None))
|
| 87 |
+
for obj in iterable
|
| 88 |
+
)
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
@experimental
|
| 92 |
+
@contextlib.contextmanager
|
| 93 |
+
def parallel_backend(backend_name: str):
|
| 94 |
+
"""
|
| 95 |
+
**Experimental.** Configures the parallel backend for parallelized dataset loading, which uses the parallelization
|
| 96 |
+
implemented by joblib.
|
| 97 |
+
|
| 98 |
+
Args:
|
| 99 |
+
backend_name (str): Name of backend for parallelization implementation, has to be supported by joblib.
|
| 100 |
+
|
| 101 |
+
Example usage:
|
| 102 |
+
```py
|
| 103 |
+
with parallel_backend('spark'):
|
| 104 |
+
dataset = load_dataset(..., num_proc=2)
|
| 105 |
+
```
|
| 106 |
+
"""
|
| 107 |
+
ParallelBackendConfig.backend_name = backend_name
|
| 108 |
+
|
| 109 |
+
if backend_name == "spark":
|
| 110 |
+
from joblibspark import register_spark
|
| 111 |
+
|
| 112 |
+
register_spark()
|
| 113 |
+
|
| 114 |
+
# TODO: call create_cache_and_write_probe if "download" in steps
|
| 115 |
+
# TODO: raise NotImplementedError when Dataset.map etc is called
|
| 116 |
+
|
| 117 |
+
try:
|
| 118 |
+
yield
|
| 119 |
+
finally:
|
| 120 |
+
ParallelBackendConfig.backend_name = None
|
bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
uv
|
bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/LICENSE
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright (c) 2004-2016 California Institute of Technology.
|
| 2 |
+
Copyright (c) 2016-2026 The Uncertainty Quantification Foundation.
|
| 3 |
+
All rights reserved.
|
| 4 |
+
|
| 5 |
+
This software is available subject to the conditions and terms laid
|
| 6 |
+
out below. By downloading and using this software you are agreeing
|
| 7 |
+
to the following conditions.
|
| 8 |
+
|
| 9 |
+
Redistribution and use in source and binary forms, with or without
|
| 10 |
+
modification, are permitted provided that the following conditions
|
| 11 |
+
are met:
|
| 12 |
+
|
| 13 |
+
- Redistributions of source code must retain the above copyright
|
| 14 |
+
notice, this list of conditions and the following disclaimer.
|
| 15 |
+
|
| 16 |
+
- Redistributions in binary form must reproduce the above copyright
|
| 17 |
+
notice, this list of conditions and the following disclaimer in the
|
| 18 |
+
documentation and/or other materials provided with the distribution.
|
| 19 |
+
|
| 20 |
+
- Neither the names of the copyright holders nor the names of any of
|
| 21 |
+
the contributors may be used to endorse or promote products derived
|
| 22 |
+
from this software without specific prior written permission.
|
| 23 |
+
|
| 24 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 25 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
| 26 |
+
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
| 27 |
+
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
| 28 |
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
| 29 |
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
| 30 |
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
| 31 |
+
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
| 32 |
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
| 33 |
+
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
| 34 |
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 35 |
+
|
bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/METADATA
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.1
|
| 2 |
+
Name: dill
|
| 3 |
+
Version: 0.4.1
|
| 4 |
+
Summary: serialize all of Python
|
| 5 |
+
Home-page: https://github.com/uqfoundation/dill
|
| 6 |
+
Download-URL: https://pypi.org/project/dill/#files
|
| 7 |
+
Author: Mike McKerns
|
| 8 |
+
Author-email: mmckerns@uqfoundation.org
|
| 9 |
+
Maintainer: Mike McKerns
|
| 10 |
+
Maintainer-email: mmckerns@uqfoundation.org
|
| 11 |
+
License: BSD-3-Clause
|
| 12 |
+
Project-URL: Documentation, http://dill.rtfd.io
|
| 13 |
+
Project-URL: Source Code, https://github.com/uqfoundation/dill
|
| 14 |
+
Project-URL: Bug Tracker, https://github.com/uqfoundation/dill/issues
|
| 15 |
+
Platform: Linux
|
| 16 |
+
Platform: Windows
|
| 17 |
+
Platform: Mac
|
| 18 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 19 |
+
Classifier: Intended Audience :: Developers
|
| 20 |
+
Classifier: Intended Audience :: Science/Research
|
| 21 |
+
Classifier: License :: OSI Approved :: BSD License
|
| 22 |
+
Classifier: Programming Language :: Python :: 3
|
| 23 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 24 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 25 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 26 |
+
Classifier: Programming Language :: Python :: 3.12
|
| 27 |
+
Classifier: Programming Language :: Python :: 3.13
|
| 28 |
+
Classifier: Programming Language :: Python :: 3.14
|
| 29 |
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
| 30 |
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
| 31 |
+
Classifier: Topic :: Scientific/Engineering
|
| 32 |
+
Classifier: Topic :: Software Development
|
| 33 |
+
Requires-Python: >=3.9
|
| 34 |
+
License-File: LICENSE
|
| 35 |
+
Provides-Extra: readline
|
| 36 |
+
Provides-Extra: graph
|
| 37 |
+
Requires-Dist: objgraph>=1.7.2; extra == "graph"
|
| 38 |
+
Provides-Extra: profile
|
| 39 |
+
Requires-Dist: gprof2dot>=2022.7.29; extra == "profile"
|
| 40 |
+
|
| 41 |
+
-----------------------------
|
| 42 |
+
dill: serialize all of Python
|
| 43 |
+
-----------------------------
|
| 44 |
+
|
| 45 |
+
About Dill
|
| 46 |
+
==========
|
| 47 |
+
|
| 48 |
+
``dill`` extends Python's ``pickle`` module for serializing and de-serializing
|
| 49 |
+
Python objects to the majority of the built-in Python types. Serialization
|
| 50 |
+
is the process of converting an object to a byte stream, and the inverse
|
| 51 |
+
of which is converting a byte stream back to a Python object hierarchy.
|
| 52 |
+
|
| 53 |
+
``dill`` provides the user the same interface as the ``pickle`` module, and
|
| 54 |
+
also includes some additional features. In addition to pickling Python
|
| 55 |
+
objects, ``dill`` provides the ability to save the state of an interpreter
|
| 56 |
+
session in a single command. Hence, it would be feasible to save an
|
| 57 |
+
interpreter session, close the interpreter, ship the pickled file to
|
| 58 |
+
another computer, open a new interpreter, unpickle the session and
|
| 59 |
+
thus continue from the 'saved' state of the original interpreter
|
| 60 |
+
session.
|
| 61 |
+
|
| 62 |
+
``dill`` can be used to store Python objects to a file, but the primary
|
| 63 |
+
usage is to send Python objects across the network as a byte stream.
|
| 64 |
+
``dill`` is quite flexible, and allows arbitrary user defined classes
|
| 65 |
+
and functions to be serialized. Thus ``dill`` is not intended to be
|
| 66 |
+
secure against erroneously or maliciously constructed data. It is
|
| 67 |
+
left to the user to decide whether the data they unpickle is from
|
| 68 |
+
a trustworthy source.
|
| 69 |
+
|
| 70 |
+
``dill`` is part of ``pathos``, a Python framework for heterogeneous computing.
|
| 71 |
+
``dill`` is in active development, so any user feedback, bug reports, comments,
|
| 72 |
+
or suggestions are highly appreciated. A list of issues is located at
|
| 73 |
+
https://github.com/uqfoundation/dill/issues, with a legacy list maintained at
|
| 74 |
+
https://uqfoundation.github.io/project/pathos/query.
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
Major Features
|
| 78 |
+
==============
|
| 79 |
+
|
| 80 |
+
``dill`` can pickle the following standard types:
|
| 81 |
+
|
| 82 |
+
- none, type, bool, int, float, complex, bytes, str,
|
| 83 |
+
- tuple, list, dict, file, buffer, builtin,
|
| 84 |
+
- Python classes, namedtuples, dataclasses, metaclasses,
|
| 85 |
+
- instances of classes,
|
| 86 |
+
- set, frozenset, array, functions, exceptions
|
| 87 |
+
|
| 88 |
+
``dill`` can also pickle more 'exotic' standard types:
|
| 89 |
+
|
| 90 |
+
- functions with yields, nested functions, lambdas,
|
| 91 |
+
- cell, method, unboundmethod, module, code, methodwrapper,
|
| 92 |
+
- methoddescriptor, getsetdescriptor, memberdescriptor, wrapperdescriptor,
|
| 93 |
+
- dictproxy, slice, notimplemented, ellipsis, quit
|
| 94 |
+
|
| 95 |
+
``dill`` cannot yet pickle these standard types:
|
| 96 |
+
|
| 97 |
+
- frame, generator, traceback
|
| 98 |
+
|
| 99 |
+
``dill`` also provides the capability to:
|
| 100 |
+
|
| 101 |
+
- save and load Python interpreter sessions
|
| 102 |
+
- save and extract the source code from functions and classes
|
| 103 |
+
- interactively diagnose pickling errors
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
Current Release
|
| 107 |
+
===============
|
| 108 |
+
|
| 109 |
+
The latest released version of ``dill`` is available from:
|
| 110 |
+
|
| 111 |
+
https://pypi.org/project/dill
|
| 112 |
+
|
| 113 |
+
``dill`` is distributed under a 3-clause BSD license.
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
Development Version
|
| 117 |
+
===================
|
| 118 |
+
|
| 119 |
+
You can get the latest development version with all the shiny new features at:
|
| 120 |
+
|
| 121 |
+
https://github.com/uqfoundation
|
| 122 |
+
|
| 123 |
+
If you have a new contribution, please submit a pull request.
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
Installation
|
| 127 |
+
============
|
| 128 |
+
|
| 129 |
+
``dill`` can be installed with ``pip``::
|
| 130 |
+
|
| 131 |
+
$ pip install dill
|
| 132 |
+
|
| 133 |
+
To optionally include the ``objgraph`` diagnostic tool in the install::
|
| 134 |
+
|
| 135 |
+
$ pip install dill[graph]
|
| 136 |
+
|
| 137 |
+
To optionally include the ``gprof2dot`` diagnostic tool in the install::
|
| 138 |
+
|
| 139 |
+
$ pip install dill[profile]
|
| 140 |
+
|
| 141 |
+
For windows users, to optionally install session history tools::
|
| 142 |
+
|
| 143 |
+
$ pip install dill[readline]
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
Requirements
|
| 147 |
+
============
|
| 148 |
+
|
| 149 |
+
``dill`` requires:
|
| 150 |
+
|
| 151 |
+
- ``python`` (or ``pypy``), **>=3.9**
|
| 152 |
+
- ``setuptools``, **>=42**
|
| 153 |
+
|
| 154 |
+
Optional requirements:
|
| 155 |
+
|
| 156 |
+
- ``objgraph``, **>=1.7.2**
|
| 157 |
+
- ``gprof2dot``, **>=2022.7.29**
|
| 158 |
+
- ``pyreadline``, **>=1.7.1** (on windows)
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
Basic Usage
|
| 162 |
+
===========
|
| 163 |
+
|
| 164 |
+
``dill`` is a drop-in replacement for ``pickle``. Existing code can be
|
| 165 |
+
updated to allow complete pickling using::
|
| 166 |
+
|
| 167 |
+
>>> import dill as pickle
|
| 168 |
+
|
| 169 |
+
or::
|
| 170 |
+
|
| 171 |
+
>>> from dill import dumps, loads
|
| 172 |
+
|
| 173 |
+
``dumps`` converts the object to a unique byte string, and ``loads`` performs
|
| 174 |
+
the inverse operation::
|
| 175 |
+
|
| 176 |
+
>>> squared = lambda x: x**2
|
| 177 |
+
>>> loads(dumps(squared))(3)
|
| 178 |
+
9
|
| 179 |
+
|
| 180 |
+
There are a number of options to control serialization which are provided
|
| 181 |
+
as keyword arguments to several ``dill`` functions:
|
| 182 |
+
|
| 183 |
+
* with *protocol*, the pickle protocol level can be set. This uses the
|
| 184 |
+
same value as the ``pickle`` module, *DEFAULT_PROTOCOL*.
|
| 185 |
+
* with *byref=True*, ``dill`` to behave a lot more like pickle with
|
| 186 |
+
certain objects (like modules) pickled by reference as opposed to
|
| 187 |
+
attempting to pickle the object itself.
|
| 188 |
+
* with *recurse=True*, objects referred to in the global dictionary are
|
| 189 |
+
recursively traced and pickled, instead of the default behavior of
|
| 190 |
+
attempting to store the entire global dictionary.
|
| 191 |
+
* with *fmode*, the contents of the file can be pickled along with the file
|
| 192 |
+
handle, which is useful if the object is being sent over the wire to a
|
| 193 |
+
remote system which does not have the original file on disk. Options are
|
| 194 |
+
*HANDLE_FMODE* for just the handle, *CONTENTS_FMODE* for the file content
|
| 195 |
+
and *FILE_FMODE* for content and handle.
|
| 196 |
+
* with *ignore=False*, objects reconstructed with types defined in the
|
| 197 |
+
top-level script environment use the existing type in the environment
|
| 198 |
+
rather than a possibly different reconstructed type.
|
| 199 |
+
|
| 200 |
+
The default serialization can also be set globally in *dill.settings*.
|
| 201 |
+
Thus, we can modify how ``dill`` handles references to the global dictionary
|
| 202 |
+
locally or globally::
|
| 203 |
+
|
| 204 |
+
>>> import dill.settings
|
| 205 |
+
>>> dumps(absolute) == dumps(absolute, recurse=True)
|
| 206 |
+
False
|
| 207 |
+
>>> dill.settings['recurse'] = True
|
| 208 |
+
>>> dumps(absolute) == dumps(absolute, recurse=True)
|
| 209 |
+
True
|
| 210 |
+
|
| 211 |
+
``dill`` also includes source code inspection, as an alternate to pickling::
|
| 212 |
+
|
| 213 |
+
>>> import dill.source
|
| 214 |
+
>>> print(dill.source.getsource(squared))
|
| 215 |
+
squared = lambda x:x**2
|
| 216 |
+
|
| 217 |
+
To aid in debugging pickling issues, use *dill.detect* which provides
|
| 218 |
+
tools like pickle tracing::
|
| 219 |
+
|
| 220 |
+
>>> import dill.detect
|
| 221 |
+
>>> with dill.detect.trace():
|
| 222 |
+
>>> dumps(squared)
|
| 223 |
+
┬ F1: <function <lambda> at 0x7fe074f8c280>
|
| 224 |
+
├┬ F2: <function _create_function at 0x7fe074c49c10>
|
| 225 |
+
│└ # F2 [34 B]
|
| 226 |
+
├┬ Co: <code object <lambda> at 0x7fe07501eb30, file "<stdin>", line 1>
|
| 227 |
+
│├┬ F2: <function _create_code at 0x7fe074c49ca0>
|
| 228 |
+
││└ # F2 [19 B]
|
| 229 |
+
│└ # Co [87 B]
|
| 230 |
+
├┬ D1: <dict object at 0x7fe0750d4680>
|
| 231 |
+
│└ # D1 [22 B]
|
| 232 |
+
├┬ D2: <dict object at 0x7fe074c5a1c0>
|
| 233 |
+
│└ # D2 [2 B]
|
| 234 |
+
├┬ D2: <dict object at 0x7fe074f903c0>
|
| 235 |
+
│├┬ D2: <dict object at 0x7fe074f8ebc0>
|
| 236 |
+
││└ # D2 [2 B]
|
| 237 |
+
│└ # D2 [23 B]
|
| 238 |
+
└ # F1 [180 B]
|
| 239 |
+
|
| 240 |
+
With trace, we see how ``dill`` stored the lambda (``F1``) by first storing
|
| 241 |
+
``_create_function``, the underlying code object (``Co``) and ``_create_code``
|
| 242 |
+
(which is used to handle code objects), then we handle the reference to
|
| 243 |
+
the global dict (``D2``) plus other dictionaries (``D1`` and ``D2``) that
|
| 244 |
+
save the lambda object's state. A ``#`` marks when the object is actually stored.
|
| 245 |
+
|
| 246 |
+
|
| 247 |
+
More Information
|
| 248 |
+
================
|
| 249 |
+
|
| 250 |
+
Probably the best way to get started is to look at the documentation at
|
| 251 |
+
http://dill.rtfd.io. Also see ``dill.tests`` for a set of scripts that
|
| 252 |
+
demonstrate how ``dill`` can serialize different Python objects. You can
|
| 253 |
+
run the test suite with ``python -m dill.tests``. The contents of any
|
| 254 |
+
pickle file can be examined with ``undill``. As ``dill`` conforms to
|
| 255 |
+
the ``pickle`` interface, the examples and documentation found at
|
| 256 |
+
http://docs.python.org/library/pickle.html also apply to ``dill``
|
| 257 |
+
if one will ``import dill as pickle``. The source code is also generally
|
| 258 |
+
well documented, so further questions may be resolved by inspecting the
|
| 259 |
+
code itself. Please feel free to submit a ticket on github, or ask a
|
| 260 |
+
question on stackoverflow (**@Mike McKerns**).
|
| 261 |
+
If you would like to share how you use ``dill`` in your work, please send
|
| 262 |
+
an email (to **mmckerns at uqfoundation dot org**).
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
Citation
|
| 266 |
+
========
|
| 267 |
+
|
| 268 |
+
If you use ``dill`` to do research that leads to publication, we ask that you
|
| 269 |
+
acknowledge use of ``dill`` by citing the following in your publication::
|
| 270 |
+
|
| 271 |
+
M.M. McKerns, L. Strand, T. Sullivan, A. Fang, M.A.G. Aivazis,
|
| 272 |
+
"Building a framework for predictive science", Proceedings of
|
| 273 |
+
the 10th Python in Science Conference, 2011;
|
| 274 |
+
http://arxiv.org/pdf/1202.1056
|
| 275 |
+
|
| 276 |
+
Michael McKerns and Michael Aivazis,
|
| 277 |
+
"pathos: a framework for heterogeneous computing", 2010- ;
|
| 278 |
+
https://uqfoundation.github.io/project/pathos
|
| 279 |
+
|
| 280 |
+
Please see https://uqfoundation.github.io/project/pathos or
|
| 281 |
+
http://arxiv.org/pdf/1202.1056 for further information.
|
bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/RECORD
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
../../../bin/get_gprof,sha256=lpXb6xvSUtU9lKE9Dw4Zy35hBLg0RsQ-01l9KNrgDuQ,2491
|
| 2 |
+
../../../bin/get_objgraph,sha256=U9yru_IE03LwChLwS6_nOZovQ29eQEb_4T92bzSYi7c,1685
|
| 3 |
+
../../../bin/undill,sha256=-J0asuqKiqJjosezK0OAgF4PX5gNaUjMfLQvxciY0iA,621
|
| 4 |
+
dill-0.4.1.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
|
| 5 |
+
dill-0.4.1.dist-info/LICENSE,sha256=9mnWO-v3ZbqqCyDYsMEZMpan4OoMIsUKMIt012qzk5w,1790
|
| 6 |
+
dill-0.4.1.dist-info/METADATA,sha256=BA1shO3fKcjBTcKu8hSWKpGYA_VXJDgk3U-Ko7SeOGg,10171
|
| 7 |
+
dill-0.4.1.dist-info/RECORD,,
|
| 8 |
+
dill-0.4.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 9 |
+
dill-0.4.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
| 10 |
+
dill-0.4.1.dist-info/top_level.txt,sha256=HLSIyYIjQzJiBvs3_-16ntezE3j6mWGTW0DT1xDd7X0,5
|
| 11 |
+
dill/__diff.py,sha256=7XCqWIelTWSLjieOIu3Xtr1mUui9YBmltP7-tvtrG-Q,7146
|
| 12 |
+
dill/__info__.py,sha256=EGg2Nh84NhPnYq1J2j6EAPixBb3psVxY-5rAWzr8prk,10756
|
| 13 |
+
dill/__init__.py,sha256=Y8usnzpfsclJxT6TvRYGarEXkWEXprv4lC2ZJ0bGM2Y,3798
|
| 14 |
+
dill/_dill.py,sha256=NdaVyGzOb5S57abYN0eFXcogocHQrTBkUru7cqw2fwM,91730
|
| 15 |
+
dill/_objects.py,sha256=_Xc7OqnZesDmKBmtkbkrBBMDzH3TIFy_vtMRtc7lsSI,20015
|
| 16 |
+
dill/_shims.py,sha256=kkIa7muWHHp9uItpNffqmbhBO4MEKPIdeyHOKxx2VF4,6635
|
| 17 |
+
dill/detect.py,sha256=VbCyNMaIVudiqM1nLmGwS-yXW6M9CkdpbkVarAmnJqU,11207
|
| 18 |
+
dill/logger.py,sha256=Z1wgU8BbSAEWBKoucYRHYrFhVLqqqTTi-BHcfsebi88,11143
|
| 19 |
+
dill/objtypes.py,sha256=3hDEnRS040mVyA3nMJp0seIiAw9SafxbuvG5tFvthfE,736
|
| 20 |
+
dill/pointers.py,sha256=zeX8XqlLBIW9vL-XH_er9HUWmInlbfWjYtva56eTmww,4467
|
| 21 |
+
dill/session.py,sha256=88DJFIQrA8733P-VKkbCq0d1lyJzckQYCrGxcPeSKeE,23541
|
| 22 |
+
dill/settings.py,sha256=DRFp2QC8xspPZ5Sb3eIB6abPp1wNuBNtCEjZ8DLY-x4,630
|
| 23 |
+
dill/source.py,sha256=GsmYf6bEPLM9rivz1Ec7G2E-tEgAoXI95CisqdcQGGA,45710
|
| 24 |
+
dill/temp.py,sha256=eFyMgZIJRUVgdRi2a4I2tZd5g3HSUFnfm5K3LV2Z93k,8027
|
| 25 |
+
dill/tests/__init__.py,sha256=8OmXwJHyWK1axs4XwCD4TimAE1U_oF6S1ZIPJ8tI8Dg,479
|
| 26 |
+
dill/tests/__main__.py,sha256=6jkJVIcrIHqHjyKOoDr95npJz4eASssTGKbuhWEqMow,899
|
| 27 |
+
dill/tests/test_abc.py,sha256=QJ5rW4-HPG0mj-K-96zwASOC-LqGa0XnzDTNW43Cnr4,4227
|
| 28 |
+
dill/tests/test_check.py,sha256=h567c9d3L-O5lc4H8lBsN5St4NkQr5Em9eAU-0l8xYA,1396
|
| 29 |
+
dill/tests/test_classdef.py,sha256=UTctS9spat_KwiubR2-05hVbMvmT5_BqZJWReDC34lM,8600
|
| 30 |
+
dill/tests/test_dataclasses.py,sha256=btxL2-lqjFOLSDf8imLZAAQ4bkm9xQwvS2VlPiIrlQY,890
|
| 31 |
+
dill/tests/test_detect.py,sha256=pm55LV1oi3xr6zmawc2pBlzSMSMkh4TwV7IuoAh3r8M,4329
|
| 32 |
+
dill/tests/test_dictviews.py,sha256=aRqVTK5DOuIoKzxWQcPenSRnvCqLyYeM2jIQsn32Tqo,1337
|
| 33 |
+
dill/tests/test_diff.py,sha256=cvfUtLcJOqlH0VcEmuIHQf69194Jy7vWoEk8pO-GLKM,2667
|
| 34 |
+
dill/tests/test_extendpickle.py,sha256=kYtoA2gr_CLo7NRdyu2fwOdPMt8yp4kVzd9hki7pZBk,1315
|
| 35 |
+
dill/tests/test_fglobals.py,sha256=dSyPOYarpytrnb723m3nAJqGp3zeTFovA7wfoZr6Z_o,1676
|
| 36 |
+
dill/tests/test_file.py,sha256=OsM189KoskuN84bag6GbYJ4OYcTy5WlHSlMWj0j0BhQ,13578
|
| 37 |
+
dill/tests/test_functions.py,sha256=40QuhQIqV-jaDvuR5pq0_Haf7Pmd9M3DYJDs2oSxjiU,4267
|
| 38 |
+
dill/tests/test_functors.py,sha256=iLv95xcaTasuqZh5LQBLa6AWrPeCxFRb-TLzhNzrMB4,930
|
| 39 |
+
dill/tests/test_logger.py,sha256=W0QJMVMQOUOizGb1sNsKInNVS76XqrM7UFyEX-Ei_bs,2385
|
| 40 |
+
dill/tests/test_mixins.py,sha256=tlCp5-NYObO7VIiK0YkciB7yRqepRJPd_RYAc79Zcvw,4007
|
| 41 |
+
dill/tests/test_module.py,sha256=LVdwwdkdbRofoEHhOfszi7oVEUoE__YZyyJzRyza_Ws,1943
|
| 42 |
+
dill/tests/test_moduledict.py,sha256=s5siniJxn78G83lPiQnx4eYV6Z6isCU3m2phgRTtlVA,1182
|
| 43 |
+
dill/tests/test_nested.py,sha256=EuyAWkXGuERTaUaPQDOxhO1cvDhCDWPML3vYOQ0HpFg,3146
|
| 44 |
+
dill/tests/test_objects.py,sha256=6Gy-YuVDuX1efV_pQEbCen7ZpMxTazY9Ihq7y1otesQ,1931
|
| 45 |
+
dill/tests/test_properties.py,sha256=ex9gCfebSawz6n5RGLS4NK5tyC7zjULJBYqPSl33Yqs,1346
|
| 46 |
+
dill/tests/test_pycapsule.py,sha256=EJFsKZ0kTWi17YOQ0wwaoglXP9XqDS83EYIr1-ZsNUk,1417
|
| 47 |
+
dill/tests/test_recursive.py,sha256=5zwJ62LHCtd3lFsFX7__XqflV78QKwuv-hnvBISoiVs,4182
|
| 48 |
+
dill/tests/test_registered.py,sha256=fO2J8t1VlNFd6ecUtd8akgjl4nRy5TldZbnBEzymtWE,1573
|
| 49 |
+
dill/tests/test_restricted.py,sha256=MG6gWcyn1X2kMNL7hX40iTZNbtre8-6QwneTt6EW7eE,783
|
| 50 |
+
dill/tests/test_selected.py,sha256=1lr05NaRqy27XV-xj5A93Mh8vuOEVXbZZ_ELgjyBPl0,3069
|
| 51 |
+
dill/tests/test_session.py,sha256=fILaOGfRHdMd7wED2fqkRHkHlRLY13TaTnvWIcbP8ic,10161
|
| 52 |
+
dill/tests/test_source.py,sha256=3QnPpuQovYz0wAxzH7U4LWaGWI0sejOra8qPRgGj8W0,7311
|
| 53 |
+
dill/tests/test_sources.py,sha256=QWX_Oc3NjpiMZqLLIJsXpK7kGGOYFDv47rCt7HIX_7s,8672
|
| 54 |
+
dill/tests/test_temp.py,sha256=81i8qP5zFbX7bBlXBiYMDlm_p5GTvze6zVtAPifaD_g,2619
|
| 55 |
+
dill/tests/test_threads.py,sha256=a8GRhk81_gE-TsLX21BG8Jb85vRaDd8All2AafqKzHA,1257
|
| 56 |
+
dill/tests/test_weakref.py,sha256=vKT130ADMeqzhD3vx8KZnF5zvvkhTAaq8WD1tyACX2Y,1602
|
bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/REQUESTED
ADDED
|
File without changes
|
bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: setuptools (75.6.0)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
| 5 |
+
|
bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
dill
|
bioagent-bench/.venv/lib/python3.14/site-packages/pandas/__init__.py
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
__docformat__ = "restructuredtext"
|
| 4 |
+
|
| 5 |
+
# Let users know if they're missing any of our hard dependencies
|
| 6 |
+
# except tzdata (see https://github.com/pandas-dev/pandas/issues/63264)
|
| 7 |
+
_hard_dependencies = ("numpy", "dateutil")
|
| 8 |
+
|
| 9 |
+
for _dependency in _hard_dependencies:
|
| 10 |
+
try:
|
| 11 |
+
__import__(_dependency)
|
| 12 |
+
except ImportError as _e: # pragma: no cover
|
| 13 |
+
raise ImportError(
|
| 14 |
+
f"Unable to import required dependency {_dependency}. "
|
| 15 |
+
"Please see the traceback for details."
|
| 16 |
+
) from _e
|
| 17 |
+
|
| 18 |
+
del _hard_dependencies, _dependency
|
| 19 |
+
|
| 20 |
+
try:
|
| 21 |
+
# numpy compat
|
| 22 |
+
from pandas.compat import (
|
| 23 |
+
is_numpy_dev as _is_numpy_dev, # pyright: ignore[reportUnusedImport] # noqa: F401
|
| 24 |
+
)
|
| 25 |
+
except ImportError as _err: # pragma: no cover
|
| 26 |
+
_module = _err.name
|
| 27 |
+
raise ImportError(
|
| 28 |
+
f"C extension: {_module} not built. If you want to import "
|
| 29 |
+
"pandas from the source directory, you may need to run "
|
| 30 |
+
"'python -m pip install -ve . --no-build-isolation -Ceditable-verbose=true' "
|
| 31 |
+
"to build the C extensions first."
|
| 32 |
+
) from _err
|
| 33 |
+
|
| 34 |
+
from pandas._config import (
|
| 35 |
+
get_option,
|
| 36 |
+
set_option,
|
| 37 |
+
reset_option,
|
| 38 |
+
describe_option,
|
| 39 |
+
option_context,
|
| 40 |
+
options,
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
# let init-time option registration happen
|
| 44 |
+
import pandas.core.config_init # pyright: ignore[reportUnusedImport] # noqa: F401
|
| 45 |
+
|
| 46 |
+
from pandas.core.api import (
|
| 47 |
+
# dtype
|
| 48 |
+
ArrowDtype,
|
| 49 |
+
Int8Dtype,
|
| 50 |
+
Int16Dtype,
|
| 51 |
+
Int32Dtype,
|
| 52 |
+
Int64Dtype,
|
| 53 |
+
UInt8Dtype,
|
| 54 |
+
UInt16Dtype,
|
| 55 |
+
UInt32Dtype,
|
| 56 |
+
UInt64Dtype,
|
| 57 |
+
Float32Dtype,
|
| 58 |
+
Float64Dtype,
|
| 59 |
+
CategoricalDtype,
|
| 60 |
+
PeriodDtype,
|
| 61 |
+
IntervalDtype,
|
| 62 |
+
DatetimeTZDtype,
|
| 63 |
+
StringDtype,
|
| 64 |
+
BooleanDtype,
|
| 65 |
+
# missing
|
| 66 |
+
NA,
|
| 67 |
+
isna,
|
| 68 |
+
isnull,
|
| 69 |
+
notna,
|
| 70 |
+
notnull,
|
| 71 |
+
# indexes
|
| 72 |
+
Index,
|
| 73 |
+
CategoricalIndex,
|
| 74 |
+
RangeIndex,
|
| 75 |
+
MultiIndex,
|
| 76 |
+
IntervalIndex,
|
| 77 |
+
TimedeltaIndex,
|
| 78 |
+
DatetimeIndex,
|
| 79 |
+
PeriodIndex,
|
| 80 |
+
IndexSlice,
|
| 81 |
+
# tseries
|
| 82 |
+
NaT,
|
| 83 |
+
Period,
|
| 84 |
+
period_range,
|
| 85 |
+
Timedelta,
|
| 86 |
+
timedelta_range,
|
| 87 |
+
Timestamp,
|
| 88 |
+
date_range,
|
| 89 |
+
bdate_range,
|
| 90 |
+
Interval,
|
| 91 |
+
interval_range,
|
| 92 |
+
DateOffset,
|
| 93 |
+
# conversion
|
| 94 |
+
to_numeric,
|
| 95 |
+
to_datetime,
|
| 96 |
+
to_timedelta,
|
| 97 |
+
# misc
|
| 98 |
+
Flags,
|
| 99 |
+
Grouper,
|
| 100 |
+
factorize,
|
| 101 |
+
unique,
|
| 102 |
+
NamedAgg,
|
| 103 |
+
array,
|
| 104 |
+
Categorical,
|
| 105 |
+
set_eng_float_format,
|
| 106 |
+
Series,
|
| 107 |
+
DataFrame,
|
| 108 |
+
)
|
| 109 |
+
from pandas.core.col import col
|
| 110 |
+
|
| 111 |
+
from pandas.core.dtypes.dtypes import SparseDtype
|
| 112 |
+
|
| 113 |
+
from pandas.tseries.api import infer_freq
|
| 114 |
+
from pandas.tseries import offsets
|
| 115 |
+
|
| 116 |
+
from pandas.core.computation.api import eval
|
| 117 |
+
|
| 118 |
+
from pandas.core.reshape.api import (
|
| 119 |
+
concat,
|
| 120 |
+
lreshape,
|
| 121 |
+
melt,
|
| 122 |
+
wide_to_long,
|
| 123 |
+
merge,
|
| 124 |
+
merge_asof,
|
| 125 |
+
merge_ordered,
|
| 126 |
+
crosstab,
|
| 127 |
+
pivot,
|
| 128 |
+
pivot_table,
|
| 129 |
+
get_dummies,
|
| 130 |
+
from_dummies,
|
| 131 |
+
cut,
|
| 132 |
+
qcut,
|
| 133 |
+
)
|
| 134 |
+
|
| 135 |
+
from pandas import api, arrays, errors, io, plotting, tseries
|
| 136 |
+
from pandas import testing
|
| 137 |
+
from pandas.util._print_versions import show_versions
|
| 138 |
+
|
| 139 |
+
from pandas.io.api import (
|
| 140 |
+
# excel
|
| 141 |
+
ExcelFile,
|
| 142 |
+
ExcelWriter,
|
| 143 |
+
read_excel,
|
| 144 |
+
# parsers
|
| 145 |
+
read_csv,
|
| 146 |
+
read_fwf,
|
| 147 |
+
read_table,
|
| 148 |
+
# pickle
|
| 149 |
+
read_pickle,
|
| 150 |
+
to_pickle,
|
| 151 |
+
# pytables
|
| 152 |
+
HDFStore,
|
| 153 |
+
read_hdf,
|
| 154 |
+
# sql
|
| 155 |
+
read_sql,
|
| 156 |
+
read_sql_query,
|
| 157 |
+
read_sql_table,
|
| 158 |
+
# misc
|
| 159 |
+
read_clipboard,
|
| 160 |
+
read_parquet,
|
| 161 |
+
read_orc,
|
| 162 |
+
read_feather,
|
| 163 |
+
read_html,
|
| 164 |
+
read_xml,
|
| 165 |
+
read_json,
|
| 166 |
+
read_stata,
|
| 167 |
+
read_sas,
|
| 168 |
+
read_spss,
|
| 169 |
+
read_iceberg,
|
| 170 |
+
)
|
| 171 |
+
|
| 172 |
+
from pandas.io.json._normalize import json_normalize
|
| 173 |
+
|
| 174 |
+
from pandas.util._tester import test
|
| 175 |
+
|
| 176 |
+
# use the closest tagged version if possible
|
| 177 |
+
_built_with_meson = False
|
| 178 |
+
try:
|
| 179 |
+
from pandas._version_meson import ( # pyright: ignore [reportMissingImports]
|
| 180 |
+
__version__,
|
| 181 |
+
__git_version__,
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
_built_with_meson = True
|
| 185 |
+
except ImportError:
|
| 186 |
+
from pandas._version import get_versions
|
| 187 |
+
|
| 188 |
+
v = get_versions()
|
| 189 |
+
__version__ = v.get("closest-tag", v["version"])
|
| 190 |
+
__git_version__ = v.get("full-revisionid")
|
| 191 |
+
del get_versions, v
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
# module level doc-string
|
| 195 |
+
__doc__ = """
|
| 196 |
+
pandas - a powerful data analysis and manipulation library for Python
|
| 197 |
+
=====================================================================
|
| 198 |
+
|
| 199 |
+
**pandas** is a Python package providing fast, flexible, and expressive data
|
| 200 |
+
structures designed to make working with "relational" or "labeled" data both
|
| 201 |
+
easy and intuitive. It aims to be the fundamental high-level building block for
|
| 202 |
+
doing practical, **real world** data analysis in Python. Additionally, it has
|
| 203 |
+
the broader goal of becoming **the most powerful and flexible open source data
|
| 204 |
+
analysis / manipulation tool available in any language**. It is already well on
|
| 205 |
+
its way toward this goal.
|
| 206 |
+
|
| 207 |
+
Main Features
|
| 208 |
+
-------------
|
| 209 |
+
Here are just a few of the things that pandas does well:
|
| 210 |
+
|
| 211 |
+
- Easy handling of missing data in floating point as well as non-floating
|
| 212 |
+
point data.
|
| 213 |
+
- Size mutability: columns can be inserted and deleted from DataFrame and
|
| 214 |
+
higher dimensional objects
|
| 215 |
+
- Automatic and explicit data alignment: objects can be explicitly aligned
|
| 216 |
+
to a set of labels, or the user can simply ignore the labels and let
|
| 217 |
+
`Series`, `DataFrame`, etc. automatically align the data for you in
|
| 218 |
+
computations.
|
| 219 |
+
- Powerful, flexible group by functionality to perform split-apply-combine
|
| 220 |
+
operations on data sets, for both aggregating and transforming data.
|
| 221 |
+
- Make it easy to convert ragged, differently-indexed data in other Python
|
| 222 |
+
and NumPy data structures into DataFrame objects.
|
| 223 |
+
- Intelligent label-based slicing, fancy indexing, and subsetting of large
|
| 224 |
+
data sets.
|
| 225 |
+
- Intuitive merging and joining data sets.
|
| 226 |
+
- Flexible reshaping and pivoting of data sets.
|
| 227 |
+
- Hierarchical labeling of axes (possible to have multiple labels per tick).
|
| 228 |
+
- Robust IO tools for loading data from flat files (CSV and delimited),
|
| 229 |
+
Excel files, databases, and saving/loading data from the ultrafast HDF5
|
| 230 |
+
format.
|
| 231 |
+
- Time series-specific functionality: date range generation and frequency
|
| 232 |
+
conversion, moving window statistics, date shifting and lagging.
|
| 233 |
+
"""
|
| 234 |
+
|
| 235 |
+
# Use __all__ to let type checkers know what is part of the public API.
|
| 236 |
+
# Pandas is not (yet) a py.typed library: the public API is determined
|
| 237 |
+
# based on the documentation.
|
| 238 |
+
__all__ = [
|
| 239 |
+
"NA",
|
| 240 |
+
"ArrowDtype",
|
| 241 |
+
"BooleanDtype",
|
| 242 |
+
"Categorical",
|
| 243 |
+
"CategoricalDtype",
|
| 244 |
+
"CategoricalIndex",
|
| 245 |
+
"DataFrame",
|
| 246 |
+
"DateOffset",
|
| 247 |
+
"DatetimeIndex",
|
| 248 |
+
"DatetimeTZDtype",
|
| 249 |
+
"ExcelFile",
|
| 250 |
+
"ExcelWriter",
|
| 251 |
+
"Flags",
|
| 252 |
+
"Float32Dtype",
|
| 253 |
+
"Float64Dtype",
|
| 254 |
+
"Grouper",
|
| 255 |
+
"HDFStore",
|
| 256 |
+
"Index",
|
| 257 |
+
"IndexSlice",
|
| 258 |
+
"Int8Dtype",
|
| 259 |
+
"Int16Dtype",
|
| 260 |
+
"Int32Dtype",
|
| 261 |
+
"Int64Dtype",
|
| 262 |
+
"Interval",
|
| 263 |
+
"IntervalDtype",
|
| 264 |
+
"IntervalIndex",
|
| 265 |
+
"MultiIndex",
|
| 266 |
+
"NaT",
|
| 267 |
+
"NamedAgg",
|
| 268 |
+
"Period",
|
| 269 |
+
"PeriodDtype",
|
| 270 |
+
"PeriodIndex",
|
| 271 |
+
"RangeIndex",
|
| 272 |
+
"Series",
|
| 273 |
+
"SparseDtype",
|
| 274 |
+
"StringDtype",
|
| 275 |
+
"Timedelta",
|
| 276 |
+
"TimedeltaIndex",
|
| 277 |
+
"Timestamp",
|
| 278 |
+
"UInt8Dtype",
|
| 279 |
+
"UInt16Dtype",
|
| 280 |
+
"UInt32Dtype",
|
| 281 |
+
"UInt64Dtype",
|
| 282 |
+
"api",
|
| 283 |
+
"array",
|
| 284 |
+
"arrays",
|
| 285 |
+
"bdate_range",
|
| 286 |
+
"col",
|
| 287 |
+
"concat",
|
| 288 |
+
"crosstab",
|
| 289 |
+
"cut",
|
| 290 |
+
"date_range",
|
| 291 |
+
"describe_option",
|
| 292 |
+
"errors",
|
| 293 |
+
"eval",
|
| 294 |
+
"factorize",
|
| 295 |
+
"from_dummies",
|
| 296 |
+
"get_dummies",
|
| 297 |
+
"get_option",
|
| 298 |
+
"infer_freq",
|
| 299 |
+
"interval_range",
|
| 300 |
+
"io",
|
| 301 |
+
"isna",
|
| 302 |
+
"isnull",
|
| 303 |
+
"json_normalize",
|
| 304 |
+
"lreshape",
|
| 305 |
+
"melt",
|
| 306 |
+
"merge",
|
| 307 |
+
"merge_asof",
|
| 308 |
+
"merge_ordered",
|
| 309 |
+
"notna",
|
| 310 |
+
"notnull",
|
| 311 |
+
"offsets",
|
| 312 |
+
"option_context",
|
| 313 |
+
"options",
|
| 314 |
+
"period_range",
|
| 315 |
+
"pivot",
|
| 316 |
+
"pivot_table",
|
| 317 |
+
"plotting",
|
| 318 |
+
"qcut",
|
| 319 |
+
"read_clipboard",
|
| 320 |
+
"read_csv",
|
| 321 |
+
"read_excel",
|
| 322 |
+
"read_feather",
|
| 323 |
+
"read_fwf",
|
| 324 |
+
"read_hdf",
|
| 325 |
+
"read_html",
|
| 326 |
+
"read_iceberg",
|
| 327 |
+
"read_json",
|
| 328 |
+
"read_orc",
|
| 329 |
+
"read_parquet",
|
| 330 |
+
"read_pickle",
|
| 331 |
+
"read_sas",
|
| 332 |
+
"read_spss",
|
| 333 |
+
"read_sql",
|
| 334 |
+
"read_sql_query",
|
| 335 |
+
"read_sql_table",
|
| 336 |
+
"read_stata",
|
| 337 |
+
"read_table",
|
| 338 |
+
"read_xml",
|
| 339 |
+
"reset_option",
|
| 340 |
+
"set_eng_float_format",
|
| 341 |
+
"set_option",
|
| 342 |
+
"show_versions",
|
| 343 |
+
"test",
|
| 344 |
+
"testing",
|
| 345 |
+
"timedelta_range",
|
| 346 |
+
"to_datetime",
|
| 347 |
+
"to_numeric",
|
| 348 |
+
"to_pickle",
|
| 349 |
+
"to_timedelta",
|
| 350 |
+
"tseries",
|
| 351 |
+
"unique",
|
| 352 |
+
"wide_to_long",
|
| 353 |
+
]
|
bioagent-bench/.venv/lib/python3.14/site-packages/pandas/_typing.py
ADDED
|
@@ -0,0 +1,578 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from builtins import type as type_t # pyright: ignore[reportUnusedImport]
|
| 4 |
+
from collections.abc import (
|
| 5 |
+
Callable,
|
| 6 |
+
Hashable,
|
| 7 |
+
Iterator,
|
| 8 |
+
Mapping,
|
| 9 |
+
MutableMapping,
|
| 10 |
+
Sequence,
|
| 11 |
+
)
|
| 12 |
+
from datetime import (
|
| 13 |
+
date,
|
| 14 |
+
datetime,
|
| 15 |
+
timedelta,
|
| 16 |
+
tzinfo,
|
| 17 |
+
)
|
| 18 |
+
from os import PathLike
|
| 19 |
+
from typing import (
|
| 20 |
+
TYPE_CHECKING,
|
| 21 |
+
Any,
|
| 22 |
+
Literal,
|
| 23 |
+
ParamSpec,
|
| 24 |
+
Protocol,
|
| 25 |
+
SupportsIndex,
|
| 26 |
+
TypeAlias,
|
| 27 |
+
TypeVar,
|
| 28 |
+
Union,
|
| 29 |
+
overload,
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
import numpy as np
|
| 33 |
+
import numpy.typing as npt
|
| 34 |
+
|
| 35 |
+
# To prevent import cycles place any internal imports in the branch below
|
| 36 |
+
# and use a string literal forward reference to it in subsequent types
|
| 37 |
+
# https://mypy.readthedocs.io/en/latest/common_issues.html#import-cycles
|
| 38 |
+
|
| 39 |
+
# Note that Union is needed when a Union includes a pandas type
|
| 40 |
+
|
| 41 |
+
if TYPE_CHECKING:
|
| 42 |
+
from pandas._libs import (
|
| 43 |
+
NaTType,
|
| 44 |
+
Period,
|
| 45 |
+
Timedelta,
|
| 46 |
+
Timestamp,
|
| 47 |
+
)
|
| 48 |
+
from pandas._libs.tslibs import BaseOffset
|
| 49 |
+
|
| 50 |
+
from pandas.core.dtypes.dtypes import ExtensionDtype
|
| 51 |
+
|
| 52 |
+
from pandas import (
|
| 53 |
+
DatetimeIndex,
|
| 54 |
+
Interval,
|
| 55 |
+
PeriodIndex,
|
| 56 |
+
TimedeltaIndex,
|
| 57 |
+
)
|
| 58 |
+
from pandas.arrays import (
|
| 59 |
+
DatetimeArray,
|
| 60 |
+
TimedeltaArray,
|
| 61 |
+
)
|
| 62 |
+
from pandas.core.arrays.base import ExtensionArray
|
| 63 |
+
from pandas.core.frame import DataFrame
|
| 64 |
+
from pandas.core.generic import NDFrame
|
| 65 |
+
from pandas.core.groupby.generic import (
|
| 66 |
+
DataFrameGroupBy,
|
| 67 |
+
GroupBy,
|
| 68 |
+
SeriesGroupBy,
|
| 69 |
+
)
|
| 70 |
+
from pandas.core.indexes.base import Index
|
| 71 |
+
from pandas.core.internals import (
|
| 72 |
+
BlockManager,
|
| 73 |
+
SingleBlockManager,
|
| 74 |
+
)
|
| 75 |
+
from pandas.core.resample import Resampler
|
| 76 |
+
from pandas.core.series import Series
|
| 77 |
+
from pandas.core.window.rolling import BaseWindow
|
| 78 |
+
|
| 79 |
+
from pandas.io.formats.format import EngFormatter
|
| 80 |
+
from pandas.tseries.holiday import AbstractHolidayCalendar
|
| 81 |
+
|
| 82 |
+
ScalarLike_co: TypeAlias = int | float | complex | str | bytes | np.generic
|
| 83 |
+
|
| 84 |
+
# numpy compatible types
|
| 85 |
+
NumpyValueArrayLike: TypeAlias = ScalarLike_co | npt.ArrayLike
|
| 86 |
+
NumpySorter: TypeAlias = npt.NDArray[np.integer] | None
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
P = ParamSpec("P")
|
| 90 |
+
|
| 91 |
+
HashableT = TypeVar("HashableT", bound=Hashable)
|
| 92 |
+
HashableT2 = TypeVar("HashableT2", bound=Hashable)
|
| 93 |
+
MutableMappingT = TypeVar("MutableMappingT", bound=MutableMapping)
|
| 94 |
+
|
| 95 |
+
# array-like
|
| 96 |
+
|
| 97 |
+
ArrayLike: TypeAlias = Union["ExtensionArray", np.ndarray]
|
| 98 |
+
ArrayLikeT = TypeVar("ArrayLikeT", "ExtensionArray", np.ndarray)
|
| 99 |
+
AnyArrayLike: TypeAlias = Union[ArrayLike, "Index", "Series"]
|
| 100 |
+
TimeArrayLike: TypeAlias = Union["DatetimeArray", "TimedeltaArray"]
|
| 101 |
+
|
| 102 |
+
# list-like
|
| 103 |
+
|
| 104 |
+
# from https://github.com/hauntsaninja/useful_types
|
| 105 |
+
# includes Sequence-like objects but excludes str and bytes
|
| 106 |
+
_T_co = TypeVar("_T_co", covariant=True)
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
class SequenceNotStr(Protocol[_T_co]):
|
| 110 |
+
__module__: str = "pandas.api.typing.aliases"
|
| 111 |
+
|
| 112 |
+
@overload
|
| 113 |
+
def __getitem__(self, index: SupportsIndex, /) -> _T_co: ...
|
| 114 |
+
|
| 115 |
+
@overload
|
| 116 |
+
def __getitem__(self, index: slice, /) -> Sequence[_T_co]: ...
|
| 117 |
+
|
| 118 |
+
def __contains__(self, value: object, /) -> bool: ...
|
| 119 |
+
|
| 120 |
+
def __len__(self) -> int: ...
|
| 121 |
+
|
| 122 |
+
def __iter__(self) -> Iterator[_T_co]: ...
|
| 123 |
+
|
| 124 |
+
def index(self, value: Any, start: int = ..., stop: int = ..., /) -> int: ...
|
| 125 |
+
|
| 126 |
+
def count(self, value: Any, /) -> int: ...
|
| 127 |
+
|
| 128 |
+
def __reversed__(self) -> Iterator[_T_co]: ...
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
ListLike: TypeAlias = AnyArrayLike | SequenceNotStr | range
|
| 132 |
+
|
| 133 |
+
# scalars
|
| 134 |
+
|
| 135 |
+
PythonScalar: TypeAlias = str | float | bool
|
| 136 |
+
DatetimeLikeScalar: TypeAlias = Union["Period", "Timestamp", "Timedelta"]
|
| 137 |
+
|
| 138 |
+
# aligned with pandas-stubs - typical scalars found in Series. Explicitly leaves
|
| 139 |
+
# out object
|
| 140 |
+
_IndexIterScalar: TypeAlias = Union[
|
| 141 |
+
str,
|
| 142 |
+
bytes,
|
| 143 |
+
date,
|
| 144 |
+
datetime,
|
| 145 |
+
timedelta,
|
| 146 |
+
np.datetime64,
|
| 147 |
+
np.timedelta64,
|
| 148 |
+
bool,
|
| 149 |
+
int,
|
| 150 |
+
float,
|
| 151 |
+
"Timestamp",
|
| 152 |
+
"Timedelta",
|
| 153 |
+
]
|
| 154 |
+
Scalar: TypeAlias = Union[
|
| 155 |
+
_IndexIterScalar, "Interval", complex, np.integer, np.floating, np.complexfloating
|
| 156 |
+
]
|
| 157 |
+
|
| 158 |
+
IntStrT = TypeVar("IntStrT", bound=int | str)
|
| 159 |
+
|
| 160 |
+
# timestamp and timedelta convertible types
|
| 161 |
+
|
| 162 |
+
TimestampConvertibleTypes: TypeAlias = Union[
|
| 163 |
+
"Timestamp", date, np.datetime64, np.int64, float, str
|
| 164 |
+
]
|
| 165 |
+
TimestampNonexistent: TypeAlias = (
|
| 166 |
+
Literal["shift_forward", "shift_backward", "NaT", "raise"] | timedelta
|
| 167 |
+
)
|
| 168 |
+
|
| 169 |
+
TimedeltaConvertibleTypes: TypeAlias = Union[
|
| 170 |
+
"Timedelta", timedelta, np.timedelta64, np.int64, float, str
|
| 171 |
+
]
|
| 172 |
+
Timezone: TypeAlias = str | tzinfo
|
| 173 |
+
|
| 174 |
+
ToTimestampHow: TypeAlias = Literal["s", "e", "start", "end"]
|
| 175 |
+
|
| 176 |
+
# NDFrameT is stricter and ensures that the same subclass of NDFrame always is
|
| 177 |
+
# used. E.g. `def func(a: NDFrameT) -> NDFrameT: ...` means that if a
|
| 178 |
+
# Series is passed into a function, a Series is always returned and if a DataFrame is
|
| 179 |
+
# passed in, a DataFrame is always returned.
|
| 180 |
+
NDFrameT = TypeVar("NDFrameT", bound="NDFrame")
|
| 181 |
+
|
| 182 |
+
IndexT = TypeVar("IndexT", bound="Index")
|
| 183 |
+
FreqIndexT = TypeVar("FreqIndexT", "DatetimeIndex", "PeriodIndex", "TimedeltaIndex")
|
| 184 |
+
NumpyIndexT = TypeVar("NumpyIndexT", np.ndarray, "Index")
|
| 185 |
+
|
| 186 |
+
AxisInt: TypeAlias = int
|
| 187 |
+
Axis: TypeAlias = AxisInt | Literal["index", "columns", "rows"]
|
| 188 |
+
IndexLabel: TypeAlias = Hashable | Sequence[Hashable]
|
| 189 |
+
Level: TypeAlias = Hashable
|
| 190 |
+
Shape: TypeAlias = tuple[int, ...]
|
| 191 |
+
Suffixes: TypeAlias = Sequence[str | None]
|
| 192 |
+
Ordered: TypeAlias = bool | None
|
| 193 |
+
JSONSerializable: TypeAlias = PythonScalar | list | dict | None
|
| 194 |
+
Frequency: TypeAlias = Union[str, "BaseOffset"]
|
| 195 |
+
Axes: TypeAlias = ListLike
|
| 196 |
+
|
| 197 |
+
RandomState: TypeAlias = (
|
| 198 |
+
int
|
| 199 |
+
| np.ndarray
|
| 200 |
+
| np.random.Generator
|
| 201 |
+
| np.random.BitGenerator
|
| 202 |
+
| np.random.RandomState
|
| 203 |
+
)
|
| 204 |
+
|
| 205 |
+
|
| 206 |
+
# dtypes
|
| 207 |
+
NpDtype: TypeAlias = str | np.dtype | type[str | complex | bool | object]
|
| 208 |
+
Dtype: TypeAlias = Union["ExtensionDtype", NpDtype]
|
| 209 |
+
AstypeArg: TypeAlias = Union["ExtensionDtype", npt.DTypeLike]
|
| 210 |
+
# DtypeArg specifies all allowable dtypes in a functions its dtype argument
|
| 211 |
+
DtypeArg: TypeAlias = Dtype | Mapping[Hashable, Dtype]
|
| 212 |
+
DtypeObj: TypeAlias = Union[np.dtype, "ExtensionDtype"]
|
| 213 |
+
|
| 214 |
+
# converters
|
| 215 |
+
ConvertersArg: TypeAlias = dict[Hashable, Callable[[Dtype], Dtype]]
|
| 216 |
+
|
| 217 |
+
# parse_dates
|
| 218 |
+
ParseDatesArg: TypeAlias = (
|
| 219 |
+
bool | list[Hashable] | list[list[Hashable]] | dict[Hashable, list[Hashable]]
|
| 220 |
+
)
|
| 221 |
+
|
| 222 |
+
# For functions like rename that convert one label to another
|
| 223 |
+
Renamer: TypeAlias = Mapping[Any, Hashable] | Callable[[Any], Hashable]
|
| 224 |
+
|
| 225 |
+
# to maintain type information across generic functions and parametrization
|
| 226 |
+
T = TypeVar("T")
|
| 227 |
+
|
| 228 |
+
# used in decorators to preserve the signature of the function it decorates
|
| 229 |
+
# see https://mypy.readthedocs.io/en/stable/generics.html#declaring-decorators
|
| 230 |
+
FuncType: TypeAlias = Callable[..., Any]
|
| 231 |
+
F = TypeVar("F", bound=FuncType)
|
| 232 |
+
TypeT = TypeVar("TypeT", bound=type)
|
| 233 |
+
|
| 234 |
+
# types of vectorized key functions for DataFrame::sort_values and
|
| 235 |
+
# DataFrame::sort_index, among others
|
| 236 |
+
ValueKeyFunc: TypeAlias = Callable[["Series"], Union["Series", AnyArrayLike]] | None
|
| 237 |
+
IndexKeyFunc: TypeAlias = Callable[["Index"], Union["Index", AnyArrayLike]] | None
|
| 238 |
+
|
| 239 |
+
# types of `func` kwarg for DataFrame.aggregate and Series.aggregate
|
| 240 |
+
AggFuncTypeBase: TypeAlias = Callable | str
|
| 241 |
+
AggFuncTypeDict: TypeAlias = MutableMapping[
|
| 242 |
+
Hashable, AggFuncTypeBase | list[AggFuncTypeBase]
|
| 243 |
+
]
|
| 244 |
+
AggFuncType: TypeAlias = AggFuncTypeBase | list[AggFuncTypeBase] | AggFuncTypeDict
|
| 245 |
+
AggObjType: TypeAlias = Union[
|
| 246 |
+
"Series",
|
| 247 |
+
"DataFrame",
|
| 248 |
+
"GroupBy",
|
| 249 |
+
"SeriesGroupBy",
|
| 250 |
+
"DataFrameGroupBy",
|
| 251 |
+
"BaseWindow",
|
| 252 |
+
"Resampler",
|
| 253 |
+
]
|
| 254 |
+
|
| 255 |
+
PythonFuncType: TypeAlias = Callable[[Any], Any]
|
| 256 |
+
|
| 257 |
+
# filenames and file-like-objects
|
| 258 |
+
AnyStr_co = TypeVar("AnyStr_co", str, bytes, covariant=True)
|
| 259 |
+
AnyStr_contra = TypeVar("AnyStr_contra", str, bytes, contravariant=True)
|
| 260 |
+
|
| 261 |
+
|
| 262 |
+
class BaseBuffer(Protocol):
|
| 263 |
+
@property
|
| 264 |
+
def mode(self) -> str:
|
| 265 |
+
# for _get_filepath_or_buffer
|
| 266 |
+
...
|
| 267 |
+
|
| 268 |
+
def seek(self, offset: int, whence: int = ..., /) -> int:
|
| 269 |
+
# with one argument: gzip.GzipFile, bz2.BZ2File
|
| 270 |
+
# with two arguments: zip.ZipFile, read_sas
|
| 271 |
+
...
|
| 272 |
+
|
| 273 |
+
def seekable(self) -> bool:
|
| 274 |
+
# for bz2.BZ2File
|
| 275 |
+
...
|
| 276 |
+
|
| 277 |
+
def tell(self) -> int:
|
| 278 |
+
# for zip.ZipFile, read_stata, to_stata
|
| 279 |
+
...
|
| 280 |
+
|
| 281 |
+
|
| 282 |
+
class ReadBuffer(BaseBuffer, Protocol[AnyStr_co]):
|
| 283 |
+
__module__: str = "pandas.api.typing.aliases"
|
| 284 |
+
|
| 285 |
+
def read(self, n: int = ..., /) -> AnyStr_co:
|
| 286 |
+
# for BytesIOWrapper, gzip.GzipFile, bz2.BZ2File
|
| 287 |
+
...
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
class WriteBuffer(BaseBuffer, Protocol[AnyStr_contra]):
|
| 291 |
+
__module__: str = "pandas.api.typing.aliases"
|
| 292 |
+
|
| 293 |
+
def write(self, b: AnyStr_contra, /) -> Any:
|
| 294 |
+
# for gzip.GzipFile, bz2.BZ2File
|
| 295 |
+
...
|
| 296 |
+
|
| 297 |
+
def flush(self) -> Any:
|
| 298 |
+
# for gzip.GzipFile, bz2.BZ2File
|
| 299 |
+
...
|
| 300 |
+
|
| 301 |
+
|
| 302 |
+
class ReadPickleBuffer(ReadBuffer[bytes], Protocol):
|
| 303 |
+
__module__: str = "pandas.api.typing.aliases"
|
| 304 |
+
|
| 305 |
+
def readline(self) -> bytes: ...
|
| 306 |
+
|
| 307 |
+
|
| 308 |
+
class WriteExcelBuffer(WriteBuffer[bytes], Protocol):
|
| 309 |
+
__module__: str = "pandas.api.typing.aliases"
|
| 310 |
+
|
| 311 |
+
def truncate(self, size: int | None = ..., /) -> int: ...
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
class ReadCsvBuffer(ReadBuffer[AnyStr_co], Protocol):
|
| 315 |
+
__module__: str = "pandas.api.typing.aliases"
|
| 316 |
+
|
| 317 |
+
def __iter__(self) -> Iterator[AnyStr_co]:
|
| 318 |
+
# for engine=python
|
| 319 |
+
...
|
| 320 |
+
|
| 321 |
+
def fileno(self) -> int:
|
| 322 |
+
# for _MMapWrapper
|
| 323 |
+
...
|
| 324 |
+
|
| 325 |
+
def readline(self) -> AnyStr_co:
|
| 326 |
+
# for engine=python
|
| 327 |
+
...
|
| 328 |
+
|
| 329 |
+
@property
|
| 330 |
+
def closed(self) -> bool:
|
| 331 |
+
# for engine=pyarrow
|
| 332 |
+
...
|
| 333 |
+
|
| 334 |
+
|
| 335 |
+
FilePath: TypeAlias = str | PathLike[str]
|
| 336 |
+
|
| 337 |
+
# for arbitrary kwargs passed during reading/writing files
|
| 338 |
+
StorageOptions: TypeAlias = dict[str, Any] | None
|
| 339 |
+
|
| 340 |
+
# compression keywords and compression
|
| 341 |
+
CompressionDict: TypeAlias = dict[str, Any]
|
| 342 |
+
CompressionOptions: TypeAlias = (
|
| 343 |
+
Literal["infer", "gzip", "bz2", "zip", "xz", "zstd", "tar"] | CompressionDict | None
|
| 344 |
+
)
|
| 345 |
+
ParquetCompressionOptions: TypeAlias = (
|
| 346 |
+
Literal["snappy", "gzip", "brotli", "lz4", "zstd"] | None
|
| 347 |
+
)
|
| 348 |
+
|
| 349 |
+
# types in DataFrameFormatter
|
| 350 |
+
FormattersType: TypeAlias = (
|
| 351 |
+
list[Callable] | tuple[Callable, ...] | Mapping[str | int, Callable]
|
| 352 |
+
)
|
| 353 |
+
ColspaceType: TypeAlias = Mapping[Hashable, str | int]
|
| 354 |
+
FloatFormatType: TypeAlias = Union[str, Callable, "EngFormatter"]
|
| 355 |
+
ColspaceArgType: TypeAlias = (
|
| 356 |
+
str | int | Sequence[str | int] | Mapping[Hashable, str | int]
|
| 357 |
+
)
|
| 358 |
+
|
| 359 |
+
# Arguments for fillna()
|
| 360 |
+
FillnaOptions: TypeAlias = Literal["backfill", "bfill", "ffill", "pad"]
|
| 361 |
+
InterpolateOptions: TypeAlias = Literal[
|
| 362 |
+
"linear",
|
| 363 |
+
"time",
|
| 364 |
+
"index",
|
| 365 |
+
"values",
|
| 366 |
+
"nearest",
|
| 367 |
+
"zero",
|
| 368 |
+
"slinear",
|
| 369 |
+
"quadratic",
|
| 370 |
+
"cubic",
|
| 371 |
+
"barycentric",
|
| 372 |
+
"polynomial",
|
| 373 |
+
"krogh",
|
| 374 |
+
"piecewise_polynomial",
|
| 375 |
+
"spline",
|
| 376 |
+
"pchip",
|
| 377 |
+
"akima",
|
| 378 |
+
"cubicspline",
|
| 379 |
+
"from_derivatives",
|
| 380 |
+
]
|
| 381 |
+
|
| 382 |
+
# internals
|
| 383 |
+
Manager: TypeAlias = Union["BlockManager", "SingleBlockManager"]
|
| 384 |
+
|
| 385 |
+
# indexing
|
| 386 |
+
# PositionalIndexer -> valid 1D positional indexer, e.g. can pass
|
| 387 |
+
# to ndarray.__getitem__
|
| 388 |
+
# ScalarIndexer is for a single value as the index
|
| 389 |
+
# SequenceIndexer is for list like or slices (but not tuples)
|
| 390 |
+
# PositionalIndexerTuple is extends the PositionalIndexer for 2D arrays
|
| 391 |
+
# These are used in various __getitem__ overloads
|
| 392 |
+
# TODO(typing#684): add Ellipsis, see
|
| 393 |
+
# https://github.com/python/typing/issues/684#issuecomment-548203158
|
| 394 |
+
# https://bugs.python.org/issue41810
|
| 395 |
+
# Using List[int] here rather than Sequence[int] to disallow tuples.
|
| 396 |
+
ScalarIndexer: TypeAlias = int | np.integer
|
| 397 |
+
SequenceIndexer: TypeAlias = slice | list[int] | np.ndarray
|
| 398 |
+
PositionalIndexer: TypeAlias = ScalarIndexer | SequenceIndexer
|
| 399 |
+
PositionalIndexerTuple: TypeAlias = tuple[PositionalIndexer, PositionalIndexer]
|
| 400 |
+
PositionalIndexer2D: TypeAlias = PositionalIndexer | PositionalIndexerTuple
|
| 401 |
+
TakeIndexer: TypeAlias = Sequence[int] | Sequence[np.integer] | npt.NDArray[np.integer]
|
| 402 |
+
|
| 403 |
+
# Shared by functions such as drop and astype
|
| 404 |
+
IgnoreRaise: TypeAlias = Literal["ignore", "raise"]
|
| 405 |
+
|
| 406 |
+
# Windowing rank methods
|
| 407 |
+
WindowingRankType: TypeAlias = Literal["average", "min", "max"]
|
| 408 |
+
|
| 409 |
+
# read_csv engines
|
| 410 |
+
CSVEngine: TypeAlias = Literal["c", "python", "pyarrow", "python-fwf"]
|
| 411 |
+
|
| 412 |
+
# read_json engines
|
| 413 |
+
JSONEngine: TypeAlias = Literal["ujson", "pyarrow"]
|
| 414 |
+
|
| 415 |
+
# read_xml parsers
|
| 416 |
+
XMLParsers: TypeAlias = Literal["lxml", "etree"]
|
| 417 |
+
|
| 418 |
+
# read_html flavors
|
| 419 |
+
HTMLFlavors: TypeAlias = Literal["lxml", "html5lib", "bs4"]
|
| 420 |
+
|
| 421 |
+
# Interval closed type
|
| 422 |
+
IntervalLeftRight: TypeAlias = Literal["left", "right"]
|
| 423 |
+
IntervalClosedType: TypeAlias = IntervalLeftRight | Literal["both", "neither"]
|
| 424 |
+
|
| 425 |
+
# datetime and NaTType
|
| 426 |
+
DatetimeNaTType: TypeAlias = Union[datetime, "NaTType"]
|
| 427 |
+
DateTimeErrorChoices: TypeAlias = Literal["raise", "coerce"]
|
| 428 |
+
|
| 429 |
+
# sort_index
|
| 430 |
+
SortKind: TypeAlias = Literal["quicksort", "mergesort", "heapsort", "stable"]
|
| 431 |
+
NaPosition: TypeAlias = Literal["first", "last"]
|
| 432 |
+
|
| 433 |
+
# Arguments for nsmallest and nlargest
|
| 434 |
+
NsmallestNlargestKeep: TypeAlias = Literal["first", "last", "all"]
|
| 435 |
+
|
| 436 |
+
# quantile interpolation
|
| 437 |
+
QuantileInterpolation: TypeAlias = Literal[
|
| 438 |
+
"linear", "lower", "higher", "midpoint", "nearest"
|
| 439 |
+
]
|
| 440 |
+
|
| 441 |
+
# plotting
|
| 442 |
+
PlottingOrientation: TypeAlias = Literal["horizontal", "vertical"]
|
| 443 |
+
|
| 444 |
+
# dropna
|
| 445 |
+
AnyAll: TypeAlias = Literal["any", "all"]
|
| 446 |
+
|
| 447 |
+
# merge
|
| 448 |
+
MergeHow: TypeAlias = Literal[
|
| 449 |
+
"left", "right", "inner", "outer", "cross", "left_anti", "right_anti"
|
| 450 |
+
]
|
| 451 |
+
MergeValidate: TypeAlias = Literal[
|
| 452 |
+
"one_to_one",
|
| 453 |
+
"1:1",
|
| 454 |
+
"one_to_many",
|
| 455 |
+
"1:m",
|
| 456 |
+
"many_to_one",
|
| 457 |
+
"m:1",
|
| 458 |
+
"many_to_many",
|
| 459 |
+
"m:m",
|
| 460 |
+
]
|
| 461 |
+
|
| 462 |
+
# join
|
| 463 |
+
JoinHow: TypeAlias = Literal["left", "right", "inner", "outer"]
|
| 464 |
+
JoinValidate: TypeAlias = Literal[
|
| 465 |
+
"one_to_one",
|
| 466 |
+
"1:1",
|
| 467 |
+
"one_to_many",
|
| 468 |
+
"1:m",
|
| 469 |
+
"many_to_one",
|
| 470 |
+
"m:1",
|
| 471 |
+
"many_to_many",
|
| 472 |
+
"m:m",
|
| 473 |
+
]
|
| 474 |
+
|
| 475 |
+
# reindex
|
| 476 |
+
ReindexMethod: TypeAlias = FillnaOptions | Literal["nearest"]
|
| 477 |
+
|
| 478 |
+
MatplotlibColor: TypeAlias = str | Sequence[float]
|
| 479 |
+
TimeGrouperOrigin: TypeAlias = Union[
|
| 480 |
+
"Timestamp", Literal["epoch", "start", "start_day", "end", "end_day"]
|
| 481 |
+
]
|
| 482 |
+
TimeAmbiguous: TypeAlias = (
|
| 483 |
+
Literal["infer", "NaT", "raise"] | bool | npt.NDArray[np.bool_]
|
| 484 |
+
)
|
| 485 |
+
TimeNonexistent: TypeAlias = (
|
| 486 |
+
Literal["shift_forward", "shift_backward", "NaT", "raise"] | timedelta
|
| 487 |
+
)
|
| 488 |
+
|
| 489 |
+
DropKeep: TypeAlias = Literal["first", "last", False]
|
| 490 |
+
CorrelationMethod: TypeAlias = (
|
| 491 |
+
Literal["pearson", "kendall", "spearman"]
|
| 492 |
+
| Callable[[np.ndarray, np.ndarray], float]
|
| 493 |
+
)
|
| 494 |
+
|
| 495 |
+
AlignJoin: TypeAlias = Literal["outer", "inner", "left", "right"]
|
| 496 |
+
DtypeBackend: TypeAlias = Literal["pyarrow", "numpy_nullable"]
|
| 497 |
+
|
| 498 |
+
TimeUnit: TypeAlias = Literal["s", "ms", "us", "ns"]
|
| 499 |
+
OpenFileErrors: TypeAlias = Literal[
|
| 500 |
+
"strict",
|
| 501 |
+
"ignore",
|
| 502 |
+
"replace",
|
| 503 |
+
"surrogateescape",
|
| 504 |
+
"xmlcharrefreplace",
|
| 505 |
+
"backslashreplace",
|
| 506 |
+
"namereplace",
|
| 507 |
+
]
|
| 508 |
+
|
| 509 |
+
# update
|
| 510 |
+
UpdateJoin: TypeAlias = Literal["left"]
|
| 511 |
+
|
| 512 |
+
# applymap
|
| 513 |
+
NaAction: TypeAlias = Literal["ignore"]
|
| 514 |
+
|
| 515 |
+
# from_dict
|
| 516 |
+
FromDictOrient: TypeAlias = Literal["columns", "index", "tight"]
|
| 517 |
+
|
| 518 |
+
# to_stata
|
| 519 |
+
ToStataByteorder: TypeAlias = Literal[">", "<", "little", "big"]
|
| 520 |
+
|
| 521 |
+
# ExcelWriter
|
| 522 |
+
ExcelWriterIfSheetExists: TypeAlias = Literal["error", "new", "replace", "overlay"]
|
| 523 |
+
ExcelWriterMergeCells: TypeAlias = bool | Literal["columns"]
|
| 524 |
+
|
| 525 |
+
# Offsets
|
| 526 |
+
OffsetCalendar: TypeAlias = Union[np.busdaycalendar, "AbstractHolidayCalendar"]
|
| 527 |
+
|
| 528 |
+
# read_csv: usecols
|
| 529 |
+
UsecolsArgType: TypeAlias = (
|
| 530 |
+
SequenceNotStr[Hashable] | range | AnyArrayLike | Callable[[HashableT], bool] | None
|
| 531 |
+
)
|
| 532 |
+
|
| 533 |
+
# maintain the sub-type of any hashable sequence
|
| 534 |
+
SequenceT = TypeVar("SequenceT", bound=Sequence[Hashable])
|
| 535 |
+
|
| 536 |
+
SliceType: TypeAlias = Hashable | None
|
| 537 |
+
|
| 538 |
+
|
| 539 |
+
# Arrow PyCapsule Interface
|
| 540 |
+
# from https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html#protocol-typehints
|
| 541 |
+
|
| 542 |
+
|
| 543 |
+
class ArrowArrayExportable(Protocol):
|
| 544 |
+
"""
|
| 545 |
+
An object with an ``__arrow_c_array__`` method.
|
| 546 |
+
|
| 547 |
+
This method indicates the object is an Arrow-compatible object implementing
|
| 548 |
+
the `Arrow PyCapsule Protocol`_ (exposing the `Arrow C Data Interface`_ in
|
| 549 |
+
Python), enabling zero-copy Arrow data interchange across libraries.
|
| 550 |
+
|
| 551 |
+
.. _Arrow PyCapsule Protocol: https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html
|
| 552 |
+
.. _Arrow C Data Interface: https://arrow.apache.org/docs/format/CDataInterface.html
|
| 553 |
+
|
| 554 |
+
"""
|
| 555 |
+
|
| 556 |
+
def __arrow_c_array__(
|
| 557 |
+
self, requested_schema: object | None = None
|
| 558 |
+
) -> tuple[object, object]: ...
|
| 559 |
+
|
| 560 |
+
|
| 561 |
+
class ArrowStreamExportable(Protocol):
|
| 562 |
+
"""
|
| 563 |
+
An object with an ``__arrow_c_stream__`` method.
|
| 564 |
+
|
| 565 |
+
This method indicates the object is an Arrow-compatible object implementing
|
| 566 |
+
the `Arrow PyCapsule Protocol`_ (exposing the `Arrow C Data Interface`_
|
| 567 |
+
for streams in Python), enabling zero-copy Arrow data interchange across
|
| 568 |
+
libraries.
|
| 569 |
+
|
| 570 |
+
.. _Arrow PyCapsule Protocol: https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html
|
| 571 |
+
.. _Arrow C Stream Interface: https://arrow.apache.org/docs/format/CStreamInterface.html
|
| 572 |
+
|
| 573 |
+
"""
|
| 574 |
+
|
| 575 |
+
def __arrow_c_stream__(self, requested_schema: object | None = None) -> object: ...
|
| 576 |
+
|
| 577 |
+
|
| 578 |
+
__all__ = ["type_t"]
|
bioagent-bench/.venv/lib/python3.14/site-packages/pandas/_version.py
ADDED
|
@@ -0,0 +1,692 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file helps to compute a version number in source trees obtained from
|
| 2 |
+
# git-archive tarball (such as those provided by github's download-from-tag
|
| 3 |
+
# feature). Distribution tarballs (built by setup.py sdist) and build
|
| 4 |
+
# directories (produced by setup.py build) will contain a much shorter file
|
| 5 |
+
# that just contains the computed version number.
|
| 6 |
+
|
| 7 |
+
# This file is released into the public domain.
|
| 8 |
+
# Generated by versioneer-0.28
|
| 9 |
+
# https://github.com/python-versioneer/python-versioneer
|
| 10 |
+
|
| 11 |
+
"""Git implementation of _version.py."""
|
| 12 |
+
|
| 13 |
+
from collections.abc import Callable
|
| 14 |
+
import errno
|
| 15 |
+
import functools
|
| 16 |
+
import os
|
| 17 |
+
import re
|
| 18 |
+
import subprocess
|
| 19 |
+
import sys
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def get_keywords():
|
| 23 |
+
"""Get the keywords needed to look up the version information."""
|
| 24 |
+
# these strings will be replaced by git during git-archive.
|
| 25 |
+
# setup.py/versioneer.py will grep for the variable names, so they must
|
| 26 |
+
# each be defined on a line of their own. _version.py will just call
|
| 27 |
+
# get_keywords().
|
| 28 |
+
git_refnames = " (HEAD, tag: v3.0.2, origin/3.0.x)"
|
| 29 |
+
git_full = "ab90747e3dae0e69b1bdbf083820b8075689b34b"
|
| 30 |
+
git_date = "2026-03-30 21:34:07 +0200"
|
| 31 |
+
keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
|
| 32 |
+
return keywords
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
class VersioneerConfig:
|
| 36 |
+
"""Container for Versioneer configuration parameters."""
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def get_config():
|
| 40 |
+
"""Create, populate and return the VersioneerConfig() object."""
|
| 41 |
+
# these strings are filled in when 'setup.py versioneer' creates
|
| 42 |
+
# _version.py
|
| 43 |
+
cfg = VersioneerConfig()
|
| 44 |
+
cfg.VCS = "git"
|
| 45 |
+
cfg.style = "pep440"
|
| 46 |
+
cfg.tag_prefix = "v"
|
| 47 |
+
cfg.parentdir_prefix = "pandas-"
|
| 48 |
+
cfg.versionfile_source = "pandas/_version.py"
|
| 49 |
+
cfg.verbose = False
|
| 50 |
+
return cfg
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
class NotThisMethod(Exception):
|
| 54 |
+
"""Exception raised if a method is not valid for the current scenario."""
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
LONG_VERSION_PY: dict[str, str] = {}
|
| 58 |
+
HANDLERS: dict[str, dict[str, Callable]] = {}
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
def register_vcs_handler(vcs, method): # decorator
|
| 62 |
+
"""Create decorator to mark a method as the handler of a VCS."""
|
| 63 |
+
|
| 64 |
+
def decorate(f):
|
| 65 |
+
"""Store f in HANDLERS[vcs][method]."""
|
| 66 |
+
if vcs not in HANDLERS:
|
| 67 |
+
HANDLERS[vcs] = {}
|
| 68 |
+
HANDLERS[vcs][method] = f
|
| 69 |
+
return f
|
| 70 |
+
|
| 71 |
+
return decorate
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None):
|
| 75 |
+
"""Call the given command(s)."""
|
| 76 |
+
assert isinstance(commands, list)
|
| 77 |
+
process = None
|
| 78 |
+
|
| 79 |
+
popen_kwargs = {}
|
| 80 |
+
if sys.platform == "win32":
|
| 81 |
+
# This hides the console window if pythonw.exe is used
|
| 82 |
+
startupinfo = subprocess.STARTUPINFO()
|
| 83 |
+
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
| 84 |
+
popen_kwargs["startupinfo"] = startupinfo
|
| 85 |
+
|
| 86 |
+
for command in commands:
|
| 87 |
+
dispcmd = str([command, *args])
|
| 88 |
+
try:
|
| 89 |
+
# remember shell=False, so use git.cmd on windows, not just git
|
| 90 |
+
process = subprocess.Popen(
|
| 91 |
+
[command, *args],
|
| 92 |
+
cwd=cwd,
|
| 93 |
+
env=env,
|
| 94 |
+
stdout=subprocess.PIPE,
|
| 95 |
+
stderr=(subprocess.PIPE if hide_stderr else None),
|
| 96 |
+
**popen_kwargs,
|
| 97 |
+
)
|
| 98 |
+
break
|
| 99 |
+
except OSError:
|
| 100 |
+
e = sys.exc_info()[1]
|
| 101 |
+
if e.errno == errno.ENOENT:
|
| 102 |
+
continue
|
| 103 |
+
if verbose:
|
| 104 |
+
print(f"unable to run {dispcmd}")
|
| 105 |
+
print(e)
|
| 106 |
+
return None, None
|
| 107 |
+
else:
|
| 108 |
+
if verbose:
|
| 109 |
+
print(f"unable to find command, tried {commands}")
|
| 110 |
+
return None, None
|
| 111 |
+
stdout = process.communicate()[0].strip().decode()
|
| 112 |
+
if process.returncode != 0:
|
| 113 |
+
if verbose:
|
| 114 |
+
print(f"unable to run {dispcmd} (error)")
|
| 115 |
+
print(f"stdout was {stdout}")
|
| 116 |
+
return None, process.returncode
|
| 117 |
+
return stdout, process.returncode
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
def versions_from_parentdir(parentdir_prefix, root, verbose):
|
| 121 |
+
"""Try to determine the version from the parent directory name.
|
| 122 |
+
|
| 123 |
+
Source tarballs conventionally unpack into a directory that includes both
|
| 124 |
+
the project name and a version string. We will also support searching up
|
| 125 |
+
two directory levels for an appropriately named parent directory
|
| 126 |
+
"""
|
| 127 |
+
rootdirs = []
|
| 128 |
+
|
| 129 |
+
for _ in range(3):
|
| 130 |
+
dirname = os.path.basename(root)
|
| 131 |
+
if dirname.startswith(parentdir_prefix):
|
| 132 |
+
return {
|
| 133 |
+
"version": dirname[len(parentdir_prefix) :],
|
| 134 |
+
"full-revisionid": None,
|
| 135 |
+
"dirty": False,
|
| 136 |
+
"error": None,
|
| 137 |
+
"date": None,
|
| 138 |
+
}
|
| 139 |
+
rootdirs.append(root)
|
| 140 |
+
root = os.path.dirname(root) # up a level
|
| 141 |
+
|
| 142 |
+
if verbose:
|
| 143 |
+
print(
|
| 144 |
+
f"Tried directories {rootdirs!s} \
|
| 145 |
+
but none started with prefix {parentdir_prefix}"
|
| 146 |
+
)
|
| 147 |
+
raise NotThisMethod("rootdir doesn't start with parentdir_prefix")
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
@register_vcs_handler("git", "get_keywords")
|
| 151 |
+
def git_get_keywords(versionfile_abs):
|
| 152 |
+
"""Extract version information from the given file."""
|
| 153 |
+
# the code embedded in _version.py can just fetch the value of these
|
| 154 |
+
# keywords. When used from setup.py, we don't want to import _version.py,
|
| 155 |
+
# so we do it with a regexp instead. This function is not used from
|
| 156 |
+
# _version.py.
|
| 157 |
+
keywords = {}
|
| 158 |
+
try:
|
| 159 |
+
with open(versionfile_abs, encoding="utf-8") as fobj:
|
| 160 |
+
for line in fobj:
|
| 161 |
+
if line.strip().startswith("git_refnames ="):
|
| 162 |
+
mo = re.search(r'=\s*"(.*)"', line)
|
| 163 |
+
if mo:
|
| 164 |
+
keywords["refnames"] = mo.group(1)
|
| 165 |
+
if line.strip().startswith("git_full ="):
|
| 166 |
+
mo = re.search(r'=\s*"(.*)"', line)
|
| 167 |
+
if mo:
|
| 168 |
+
keywords["full"] = mo.group(1)
|
| 169 |
+
if line.strip().startswith("git_date ="):
|
| 170 |
+
mo = re.search(r'=\s*"(.*)"', line)
|
| 171 |
+
if mo:
|
| 172 |
+
keywords["date"] = mo.group(1)
|
| 173 |
+
except OSError:
|
| 174 |
+
pass
|
| 175 |
+
return keywords
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
@register_vcs_handler("git", "keywords")
|
| 179 |
+
def git_versions_from_keywords(keywords, tag_prefix, verbose):
|
| 180 |
+
"""Get version information from git keywords."""
|
| 181 |
+
if "refnames" not in keywords:
|
| 182 |
+
raise NotThisMethod("Short version file found")
|
| 183 |
+
date = keywords.get("date")
|
| 184 |
+
if date is not None:
|
| 185 |
+
# Use only the last line. Previous lines may contain GPG signature
|
| 186 |
+
# information.
|
| 187 |
+
date = date.splitlines()[-1]
|
| 188 |
+
|
| 189 |
+
# git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
|
| 190 |
+
# datestamp. However we prefer "%ci" (which expands to an "ISO-8601
|
| 191 |
+
# -like" string, which we must then edit to make compliant), because
|
| 192 |
+
# it's been around since git-1.5.3, and it's too difficult to
|
| 193 |
+
# discover which version we're using, or to work around using an
|
| 194 |
+
# older one.
|
| 195 |
+
date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
|
| 196 |
+
refnames = keywords["refnames"].strip()
|
| 197 |
+
if refnames.startswith("$Format"):
|
| 198 |
+
if verbose:
|
| 199 |
+
print("keywords are unexpanded, not using")
|
| 200 |
+
raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
|
| 201 |
+
refs = {r.strip() for r in refnames.strip("()").split(",")}
|
| 202 |
+
# starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
|
| 203 |
+
# just "foo-1.0". If we see a "tag: " prefix, prefer those.
|
| 204 |
+
TAG = "tag: "
|
| 205 |
+
tags = {r[len(TAG) :] for r in refs if r.startswith(TAG)}
|
| 206 |
+
if not tags:
|
| 207 |
+
# Either we're using git < 1.8.3, or there really are no tags. We use
|
| 208 |
+
# a heuristic: assume all version tags have a digit. The old git %d
|
| 209 |
+
# expansion behaves like git log --decorate=short and strips out the
|
| 210 |
+
# refs/heads/ and refs/tags/ prefixes that would let us distinguish
|
| 211 |
+
# between branches and tags. By ignoring refnames without digits, we
|
| 212 |
+
# filter out many common branch names like "release" and
|
| 213 |
+
# "stabilization", as well as "HEAD" and "master".
|
| 214 |
+
tags = {r for r in refs if re.search(r"\d", r)}
|
| 215 |
+
if verbose:
|
| 216 |
+
print(f"discarding '{','.join(refs - tags)}', no digits")
|
| 217 |
+
if verbose:
|
| 218 |
+
print(f"likely tags: {','.join(sorted(tags))}")
|
| 219 |
+
for ref in sorted(tags):
|
| 220 |
+
# sorting will prefer e.g. "2.0" over "2.0rc1"
|
| 221 |
+
if ref.startswith(tag_prefix):
|
| 222 |
+
r = ref[len(tag_prefix) :]
|
| 223 |
+
# Filter out refs that exactly match prefix or that don't start
|
| 224 |
+
# with a number once the prefix is stripped (mostly a concern
|
| 225 |
+
# when prefix is '')
|
| 226 |
+
if not re.match(r"\d", r):
|
| 227 |
+
continue
|
| 228 |
+
if verbose:
|
| 229 |
+
print(f"picking {r}")
|
| 230 |
+
return {
|
| 231 |
+
"version": r,
|
| 232 |
+
"full-revisionid": keywords["full"].strip(),
|
| 233 |
+
"dirty": False,
|
| 234 |
+
"error": None,
|
| 235 |
+
"date": date,
|
| 236 |
+
}
|
| 237 |
+
# no suitable tags, so version is "0+unknown", but full hex is still there
|
| 238 |
+
if verbose:
|
| 239 |
+
print("no suitable tags, using unknown + full revision id")
|
| 240 |
+
return {
|
| 241 |
+
"version": "0+unknown",
|
| 242 |
+
"full-revisionid": keywords["full"].strip(),
|
| 243 |
+
"dirty": False,
|
| 244 |
+
"error": "no suitable tags",
|
| 245 |
+
"date": None,
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
|
| 249 |
+
@register_vcs_handler("git", "pieces_from_vcs")
|
| 250 |
+
def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
|
| 251 |
+
"""Get version from 'git describe' in the root of the source tree.
|
| 252 |
+
|
| 253 |
+
This only gets called if the git-archive 'subst' keywords were *not*
|
| 254 |
+
expanded, and _version.py hasn't already been rewritten with a short
|
| 255 |
+
version string, meaning we're inside a checked out source tree.
|
| 256 |
+
"""
|
| 257 |
+
GITS = ["git"]
|
| 258 |
+
if sys.platform == "win32":
|
| 259 |
+
GITS = ["git.cmd", "git.exe"]
|
| 260 |
+
|
| 261 |
+
# GIT_DIR can interfere with correct operation of Versioneer.
|
| 262 |
+
# It may be intended to be passed to the Versioneer-versioned project,
|
| 263 |
+
# but that should not change where we get our version from.
|
| 264 |
+
env = os.environ.copy()
|
| 265 |
+
env.pop("GIT_DIR", None)
|
| 266 |
+
runner = functools.partial(runner, env=env)
|
| 267 |
+
|
| 268 |
+
_, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=not verbose)
|
| 269 |
+
if rc != 0:
|
| 270 |
+
if verbose:
|
| 271 |
+
print(f"Directory {root} not under git control")
|
| 272 |
+
raise NotThisMethod("'git rev-parse --git-dir' returned error")
|
| 273 |
+
|
| 274 |
+
# if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
|
| 275 |
+
# if there isn't one, this yields HEX[-dirty] (no NUM)
|
| 276 |
+
describe_out, rc = runner(
|
| 277 |
+
GITS,
|
| 278 |
+
[
|
| 279 |
+
"describe",
|
| 280 |
+
"--tags",
|
| 281 |
+
"--dirty",
|
| 282 |
+
"--always",
|
| 283 |
+
"--long",
|
| 284 |
+
"--match",
|
| 285 |
+
f"{tag_prefix}[[:digit:]]*",
|
| 286 |
+
],
|
| 287 |
+
cwd=root,
|
| 288 |
+
)
|
| 289 |
+
# --long was added in git-1.5.5
|
| 290 |
+
if describe_out is None:
|
| 291 |
+
raise NotThisMethod("'git describe' failed")
|
| 292 |
+
describe_out = describe_out.strip()
|
| 293 |
+
full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root)
|
| 294 |
+
if full_out is None:
|
| 295 |
+
raise NotThisMethod("'git rev-parse' failed")
|
| 296 |
+
full_out = full_out.strip()
|
| 297 |
+
|
| 298 |
+
pieces = {}
|
| 299 |
+
pieces["long"] = full_out
|
| 300 |
+
pieces["short"] = full_out[:7] # maybe improved later
|
| 301 |
+
pieces["error"] = None
|
| 302 |
+
|
| 303 |
+
branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root)
|
| 304 |
+
# --abbrev-ref was added in git-1.6.3
|
| 305 |
+
if rc != 0 or branch_name is None:
|
| 306 |
+
raise NotThisMethod("'git rev-parse --abbrev-ref' returned error")
|
| 307 |
+
branch_name = branch_name.strip()
|
| 308 |
+
|
| 309 |
+
if branch_name == "HEAD":
|
| 310 |
+
# If we aren't exactly on a branch, pick a branch which represents
|
| 311 |
+
# the current commit. If all else fails, we are on a branchless
|
| 312 |
+
# commit.
|
| 313 |
+
branches, rc = runner(GITS, ["branch", "--contains"], cwd=root)
|
| 314 |
+
# --contains was added in git-1.5.4
|
| 315 |
+
if rc != 0 or branches is None:
|
| 316 |
+
raise NotThisMethod("'git branch --contains' returned error")
|
| 317 |
+
branches = branches.split("\n")
|
| 318 |
+
|
| 319 |
+
# Remove the first line if we're running detached
|
| 320 |
+
if "(" in branches[0]:
|
| 321 |
+
branches.pop(0)
|
| 322 |
+
|
| 323 |
+
# Strip off the leading "* " from the list of branches.
|
| 324 |
+
branches = [branch[2:] for branch in branches]
|
| 325 |
+
if "master" in branches:
|
| 326 |
+
branch_name = "master"
|
| 327 |
+
elif not branches:
|
| 328 |
+
branch_name = None
|
| 329 |
+
else:
|
| 330 |
+
# Pick the first branch that is returned. Good or bad.
|
| 331 |
+
branch_name = branches[0]
|
| 332 |
+
|
| 333 |
+
pieces["branch"] = branch_name
|
| 334 |
+
|
| 335 |
+
# parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
|
| 336 |
+
# TAG might have hyphens.
|
| 337 |
+
git_describe = describe_out
|
| 338 |
+
|
| 339 |
+
# look for -dirty suffix
|
| 340 |
+
dirty = git_describe.endswith("-dirty")
|
| 341 |
+
pieces["dirty"] = dirty
|
| 342 |
+
if dirty:
|
| 343 |
+
git_describe = git_describe[: git_describe.rindex("-dirty")]
|
| 344 |
+
|
| 345 |
+
# now we have TAG-NUM-gHEX or HEX
|
| 346 |
+
|
| 347 |
+
if "-" in git_describe:
|
| 348 |
+
# TAG-NUM-gHEX
|
| 349 |
+
mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe)
|
| 350 |
+
if not mo:
|
| 351 |
+
# unparsable. Maybe git-describe is misbehaving?
|
| 352 |
+
pieces["error"] = f"unable to parse git-describe output: '{describe_out}'"
|
| 353 |
+
return pieces
|
| 354 |
+
|
| 355 |
+
# tag
|
| 356 |
+
full_tag = mo.group(1)
|
| 357 |
+
if not full_tag.startswith(tag_prefix):
|
| 358 |
+
if verbose:
|
| 359 |
+
fmt = "tag '%s' doesn't start with prefix '%s'"
|
| 360 |
+
print(fmt % (full_tag, tag_prefix))
|
| 361 |
+
pieces["error"] = (
|
| 362 |
+
f"tag '{full_tag}' doesn't start with prefix '{tag_prefix}'"
|
| 363 |
+
)
|
| 364 |
+
return pieces
|
| 365 |
+
pieces["closest-tag"] = full_tag[len(tag_prefix) :]
|
| 366 |
+
|
| 367 |
+
# distance: number of commits since tag
|
| 368 |
+
pieces["distance"] = int(mo.group(2))
|
| 369 |
+
|
| 370 |
+
# commit: short hex revision ID
|
| 371 |
+
pieces["short"] = mo.group(3)
|
| 372 |
+
|
| 373 |
+
else:
|
| 374 |
+
# HEX: no tags
|
| 375 |
+
pieces["closest-tag"] = None
|
| 376 |
+
out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root)
|
| 377 |
+
pieces["distance"] = len(out.split()) # total number of commits
|
| 378 |
+
|
| 379 |
+
# commit date: see ISO-8601 comment in git_versions_from_keywords()
|
| 380 |
+
date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip()
|
| 381 |
+
# Use only the last line. Previous lines may contain GPG signature
|
| 382 |
+
# information.
|
| 383 |
+
date = date.splitlines()[-1]
|
| 384 |
+
pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
|
| 385 |
+
|
| 386 |
+
return pieces
|
| 387 |
+
|
| 388 |
+
|
| 389 |
+
def plus_or_dot(pieces) -> str:
|
| 390 |
+
"""Return a + if we don't already have one, else return a ."""
|
| 391 |
+
if "+" in pieces.get("closest-tag", ""):
|
| 392 |
+
return "."
|
| 393 |
+
return "+"
|
| 394 |
+
|
| 395 |
+
|
| 396 |
+
def render_pep440(pieces):
|
| 397 |
+
"""Build up version string, with post-release "local version identifier".
|
| 398 |
+
|
| 399 |
+
Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
|
| 400 |
+
get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty
|
| 401 |
+
|
| 402 |
+
Exceptions:
|
| 403 |
+
1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
|
| 404 |
+
"""
|
| 405 |
+
if pieces["closest-tag"]:
|
| 406 |
+
rendered = pieces["closest-tag"]
|
| 407 |
+
if pieces["distance"] or pieces["dirty"]:
|
| 408 |
+
rendered += plus_or_dot(pieces)
|
| 409 |
+
rendered += f"{pieces['distance']}.g{pieces['short']}"
|
| 410 |
+
if pieces["dirty"]:
|
| 411 |
+
rendered += ".dirty"
|
| 412 |
+
else:
|
| 413 |
+
# exception #1
|
| 414 |
+
rendered = f"0+untagged.{pieces['distance']}.g{pieces['short']}"
|
| 415 |
+
if pieces["dirty"]:
|
| 416 |
+
rendered += ".dirty"
|
| 417 |
+
return rendered
|
| 418 |
+
|
| 419 |
+
|
| 420 |
+
def render_pep440_branch(pieces):
|
| 421 |
+
"""TAG[[.dev0]+DISTANCE.gHEX[.dirty]] .
|
| 422 |
+
|
| 423 |
+
The ".dev0" means not master branch. Note that .dev0 sorts backwards
|
| 424 |
+
(a feature branch will appear "older" than the master branch).
|
| 425 |
+
|
| 426 |
+
Exceptions:
|
| 427 |
+
1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty]
|
| 428 |
+
"""
|
| 429 |
+
if pieces["closest-tag"]:
|
| 430 |
+
rendered = pieces["closest-tag"]
|
| 431 |
+
if pieces["distance"] or pieces["dirty"]:
|
| 432 |
+
if pieces["branch"] != "master":
|
| 433 |
+
rendered += ".dev0"
|
| 434 |
+
rendered += plus_or_dot(pieces)
|
| 435 |
+
rendered += f"{pieces['distance']}.g{pieces['short']}"
|
| 436 |
+
if pieces["dirty"]:
|
| 437 |
+
rendered += ".dirty"
|
| 438 |
+
else:
|
| 439 |
+
# exception #1
|
| 440 |
+
rendered = "0"
|
| 441 |
+
if pieces["branch"] != "master":
|
| 442 |
+
rendered += ".dev0"
|
| 443 |
+
rendered += f"+untagged.{pieces['distance']}.g{pieces['short']}"
|
| 444 |
+
if pieces["dirty"]:
|
| 445 |
+
rendered += ".dirty"
|
| 446 |
+
return rendered
|
| 447 |
+
|
| 448 |
+
|
| 449 |
+
def pep440_split_post(ver):
|
| 450 |
+
"""Split pep440 version string at the post-release segment.
|
| 451 |
+
|
| 452 |
+
Returns the release segments before the post-release and the
|
| 453 |
+
post-release version number (or -1 if no post-release segment is present).
|
| 454 |
+
"""
|
| 455 |
+
vc = str.split(ver, ".post")
|
| 456 |
+
return vc[0], int(vc[1] or 0) if len(vc) == 2 else None
|
| 457 |
+
|
| 458 |
+
|
| 459 |
+
def render_pep440_pre(pieces):
|
| 460 |
+
"""TAG[.postN.devDISTANCE] -- No -dirty.
|
| 461 |
+
|
| 462 |
+
Exceptions:
|
| 463 |
+
1: no tags. 0.post0.devDISTANCE
|
| 464 |
+
"""
|
| 465 |
+
if pieces["closest-tag"]:
|
| 466 |
+
if pieces["distance"]:
|
| 467 |
+
# update the post release segment
|
| 468 |
+
tag_version, post_version = pep440_split_post(pieces["closest-tag"])
|
| 469 |
+
rendered = tag_version
|
| 470 |
+
if post_version is not None:
|
| 471 |
+
rendered += f".post{post_version + 1}.dev{pieces['distance']}"
|
| 472 |
+
else:
|
| 473 |
+
rendered += f".post0.dev{pieces['distance']}"
|
| 474 |
+
else:
|
| 475 |
+
# no commits, use the tag as the version
|
| 476 |
+
rendered = pieces["closest-tag"]
|
| 477 |
+
else:
|
| 478 |
+
# exception #1
|
| 479 |
+
rendered = f"0.post0.dev{pieces['distance']}"
|
| 480 |
+
return rendered
|
| 481 |
+
|
| 482 |
+
|
| 483 |
+
def render_pep440_post(pieces):
|
| 484 |
+
"""TAG[.postDISTANCE[.dev0]+gHEX] .
|
| 485 |
+
|
| 486 |
+
The ".dev0" means dirty. Note that .dev0 sorts backwards
|
| 487 |
+
(a dirty tree will appear "older" than the corresponding clean one),
|
| 488 |
+
but you shouldn't be releasing software with -dirty anyways.
|
| 489 |
+
|
| 490 |
+
Exceptions:
|
| 491 |
+
1: no tags. 0.postDISTANCE[.dev0]
|
| 492 |
+
"""
|
| 493 |
+
if pieces["closest-tag"]:
|
| 494 |
+
rendered = pieces["closest-tag"]
|
| 495 |
+
if pieces["distance"] or pieces["dirty"]:
|
| 496 |
+
rendered += f".post{pieces['distance']}"
|
| 497 |
+
if pieces["dirty"]:
|
| 498 |
+
rendered += ".dev0"
|
| 499 |
+
rendered += plus_or_dot(pieces)
|
| 500 |
+
rendered += f"g{pieces['short']}"
|
| 501 |
+
else:
|
| 502 |
+
# exception #1
|
| 503 |
+
rendered = f"0.post{pieces['distance']}"
|
| 504 |
+
if pieces["dirty"]:
|
| 505 |
+
rendered += ".dev0"
|
| 506 |
+
rendered += f"+g{pieces['short']}"
|
| 507 |
+
return rendered
|
| 508 |
+
|
| 509 |
+
|
| 510 |
+
def render_pep440_post_branch(pieces):
|
| 511 |
+
"""TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] .
|
| 512 |
+
|
| 513 |
+
The ".dev0" means not master branch.
|
| 514 |
+
|
| 515 |
+
Exceptions:
|
| 516 |
+
1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty]
|
| 517 |
+
"""
|
| 518 |
+
if pieces["closest-tag"]:
|
| 519 |
+
rendered = pieces["closest-tag"]
|
| 520 |
+
if pieces["distance"] or pieces["dirty"]:
|
| 521 |
+
rendered += f".post{pieces['distance']}"
|
| 522 |
+
if pieces["branch"] != "master":
|
| 523 |
+
rendered += ".dev0"
|
| 524 |
+
rendered += plus_or_dot(pieces)
|
| 525 |
+
rendered += f"g{pieces['short']}"
|
| 526 |
+
if pieces["dirty"]:
|
| 527 |
+
rendered += ".dirty"
|
| 528 |
+
else:
|
| 529 |
+
# exception #1
|
| 530 |
+
rendered = f"0.post{pieces['distance']}"
|
| 531 |
+
if pieces["branch"] != "master":
|
| 532 |
+
rendered += ".dev0"
|
| 533 |
+
rendered += f"+g{pieces['short']}"
|
| 534 |
+
if pieces["dirty"]:
|
| 535 |
+
rendered += ".dirty"
|
| 536 |
+
return rendered
|
| 537 |
+
|
| 538 |
+
|
| 539 |
+
def render_pep440_old(pieces):
|
| 540 |
+
"""TAG[.postDISTANCE[.dev0]] .
|
| 541 |
+
|
| 542 |
+
The ".dev0" means dirty.
|
| 543 |
+
|
| 544 |
+
Exceptions:
|
| 545 |
+
1: no tags. 0.postDISTANCE[.dev0]
|
| 546 |
+
"""
|
| 547 |
+
if pieces["closest-tag"]:
|
| 548 |
+
rendered = pieces["closest-tag"]
|
| 549 |
+
if pieces["distance"] or pieces["dirty"]:
|
| 550 |
+
rendered += f"0.post{pieces['distance']}"
|
| 551 |
+
if pieces["dirty"]:
|
| 552 |
+
rendered += ".dev0"
|
| 553 |
+
else:
|
| 554 |
+
# exception #1
|
| 555 |
+
rendered = f"0.post{pieces['distance']}"
|
| 556 |
+
if pieces["dirty"]:
|
| 557 |
+
rendered += ".dev0"
|
| 558 |
+
return rendered
|
| 559 |
+
|
| 560 |
+
|
| 561 |
+
def render_git_describe(pieces):
|
| 562 |
+
"""TAG[-DISTANCE-gHEX][-dirty].
|
| 563 |
+
|
| 564 |
+
Like 'git describe --tags --dirty --always'.
|
| 565 |
+
|
| 566 |
+
Exceptions:
|
| 567 |
+
1: no tags. HEX[-dirty] (note: no 'g' prefix)
|
| 568 |
+
"""
|
| 569 |
+
if pieces["closest-tag"]:
|
| 570 |
+
rendered = pieces["closest-tag"]
|
| 571 |
+
if pieces["distance"]:
|
| 572 |
+
rendered += f"-{pieces['distance']}-g{pieces['short']}"
|
| 573 |
+
else:
|
| 574 |
+
# exception #1
|
| 575 |
+
rendered = pieces["short"]
|
| 576 |
+
if pieces["dirty"]:
|
| 577 |
+
rendered += "-dirty"
|
| 578 |
+
return rendered
|
| 579 |
+
|
| 580 |
+
|
| 581 |
+
def render_git_describe_long(pieces):
|
| 582 |
+
"""TAG-DISTANCE-gHEX[-dirty].
|
| 583 |
+
|
| 584 |
+
Like 'git describe --tags --dirty --always --long'.
|
| 585 |
+
The distance/hash is unconditional.
|
| 586 |
+
|
| 587 |
+
Exceptions:
|
| 588 |
+
1: no tags. HEX[-dirty] (note: no 'g' prefix)
|
| 589 |
+
"""
|
| 590 |
+
if pieces["closest-tag"]:
|
| 591 |
+
rendered = pieces["closest-tag"]
|
| 592 |
+
rendered += f"-{pieces['distance']}-g{pieces['short']}"
|
| 593 |
+
else:
|
| 594 |
+
# exception #1
|
| 595 |
+
rendered = pieces["short"]
|
| 596 |
+
if pieces["dirty"]:
|
| 597 |
+
rendered += "-dirty"
|
| 598 |
+
return rendered
|
| 599 |
+
|
| 600 |
+
|
| 601 |
+
def render(pieces, style):
|
| 602 |
+
"""Render the given version pieces into the requested style."""
|
| 603 |
+
if pieces["error"]:
|
| 604 |
+
return {
|
| 605 |
+
"version": "unknown",
|
| 606 |
+
"full-revisionid": pieces.get("long"),
|
| 607 |
+
"dirty": None,
|
| 608 |
+
"error": pieces["error"],
|
| 609 |
+
"date": None,
|
| 610 |
+
}
|
| 611 |
+
|
| 612 |
+
if not style or style == "default":
|
| 613 |
+
style = "pep440" # the default
|
| 614 |
+
|
| 615 |
+
if style == "pep440":
|
| 616 |
+
rendered = render_pep440(pieces)
|
| 617 |
+
elif style == "pep440-branch":
|
| 618 |
+
rendered = render_pep440_branch(pieces)
|
| 619 |
+
elif style == "pep440-pre":
|
| 620 |
+
rendered = render_pep440_pre(pieces)
|
| 621 |
+
elif style == "pep440-post":
|
| 622 |
+
rendered = render_pep440_post(pieces)
|
| 623 |
+
elif style == "pep440-post-branch":
|
| 624 |
+
rendered = render_pep440_post_branch(pieces)
|
| 625 |
+
elif style == "pep440-old":
|
| 626 |
+
rendered = render_pep440_old(pieces)
|
| 627 |
+
elif style == "git-describe":
|
| 628 |
+
rendered = render_git_describe(pieces)
|
| 629 |
+
elif style == "git-describe-long":
|
| 630 |
+
rendered = render_git_describe_long(pieces)
|
| 631 |
+
else:
|
| 632 |
+
raise ValueError(f"unknown style '{style}'")
|
| 633 |
+
|
| 634 |
+
return {
|
| 635 |
+
"version": rendered,
|
| 636 |
+
"full-revisionid": pieces["long"],
|
| 637 |
+
"dirty": pieces["dirty"],
|
| 638 |
+
"error": None,
|
| 639 |
+
"date": pieces.get("date"),
|
| 640 |
+
}
|
| 641 |
+
|
| 642 |
+
|
| 643 |
+
def get_versions() -> dict:
|
| 644 |
+
"""Get version information or return default if unable to do so."""
|
| 645 |
+
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
|
| 646 |
+
# __file__, we can work backwards from there to the root. Some
|
| 647 |
+
# py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
|
| 648 |
+
# case we can only use expanded keywords.
|
| 649 |
+
|
| 650 |
+
cfg = get_config()
|
| 651 |
+
verbose = cfg.verbose
|
| 652 |
+
|
| 653 |
+
try:
|
| 654 |
+
return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose)
|
| 655 |
+
except NotThisMethod:
|
| 656 |
+
pass
|
| 657 |
+
|
| 658 |
+
try:
|
| 659 |
+
root = os.path.realpath(__file__)
|
| 660 |
+
# versionfile_source is the relative path from the top of the source
|
| 661 |
+
# tree (where the .git directory might live) to this file. Invert
|
| 662 |
+
# this to find the root from __file__.
|
| 663 |
+
for _ in cfg.versionfile_source.split("/"):
|
| 664 |
+
root = os.path.dirname(root)
|
| 665 |
+
except NameError:
|
| 666 |
+
return {
|
| 667 |
+
"version": "0+unknown",
|
| 668 |
+
"full-revisionid": None,
|
| 669 |
+
"dirty": None,
|
| 670 |
+
"error": "unable to find root of source tree",
|
| 671 |
+
"date": None,
|
| 672 |
+
}
|
| 673 |
+
|
| 674 |
+
try:
|
| 675 |
+
pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
|
| 676 |
+
return render(pieces, cfg.style)
|
| 677 |
+
except NotThisMethod:
|
| 678 |
+
pass
|
| 679 |
+
|
| 680 |
+
try:
|
| 681 |
+
if cfg.parentdir_prefix:
|
| 682 |
+
return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
|
| 683 |
+
except NotThisMethod:
|
| 684 |
+
pass
|
| 685 |
+
|
| 686 |
+
return {
|
| 687 |
+
"version": "0+unknown",
|
| 688 |
+
"full-revisionid": None,
|
| 689 |
+
"dirty": None,
|
| 690 |
+
"error": "unable to compute version",
|
| 691 |
+
"date": None,
|
| 692 |
+
}
|