czty commited on
Commit
1f4762d
·
verified ·
1 Parent(s): 219985f

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. bioagent-bench/.venv/lib/python3.14/site-packages/attr/_version_info.py +89 -0
  2. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/filesystems/__init__.py +47 -0
  3. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/__init__.py +136 -0
  4. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/formatting.py +678 -0
  5. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/jax_formatter.py +174 -0
  6. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/np_formatter.py +120 -0
  7. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/polars_formatter.py +124 -0
  8. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/tf_formatter.py +129 -0
  9. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/formatting/torch_formatter.py +130 -0
  10. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/__init__.py +0 -0
  11. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/abc.py +53 -0
  12. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/generator.py +62 -0
  13. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/parquet.py +159 -0
  14. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/spark.py +57 -0
  15. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/io/text.py +58 -0
  16. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/arrow/__init__.py +0 -0
  17. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/arrow/arrow.py +77 -0
  18. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/audiofolder/__init__.py +0 -0
  19. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/audiofolder/audiofolder.py +86 -0
  20. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/cache/__init__.py +0 -0
  21. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/cache/cache.py +195 -0
  22. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/eval/__init__.py +0 -0
  23. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/eval/eval.py +77 -0
  24. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/hdf5/hdf5.py +389 -0
  25. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/json/__init__.py +0 -0
  26. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/json/json.py +383 -0
  27. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/lance/__init__.py +0 -0
  28. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/lance/lance.py +235 -0
  29. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/niftifolder/__init__.py +0 -0
  30. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/niftifolder/niftifolder.py +23 -0
  31. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/parquet/__init__.py +0 -0
  32. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/parquet/parquet.py +217 -0
  33. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/spark/spark.py +367 -0
  34. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/text/__init__.py +0 -0
  35. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/text/text.py +137 -0
  36. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/webdataset/__init__.py +0 -0
  37. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/webdataset/_tenbin.py +285 -0
  38. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/packaged_modules/webdataset/webdataset.py +349 -0
  39. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/parallel/__init__.py +1 -0
  40. bioagent-bench/.venv/lib/python3.14/site-packages/datasets/parallel/parallel.py +120 -0
  41. bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/INSTALLER +1 -0
  42. bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/LICENSE +35 -0
  43. bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/METADATA +281 -0
  44. bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/RECORD +56 -0
  45. bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/REQUESTED +0 -0
  46. bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/WHEEL +5 -0
  47. bioagent-bench/.venv/lib/python3.14/site-packages/dill-0.4.1.dist-info/top_level.txt +1 -0
  48. bioagent-bench/.venv/lib/python3.14/site-packages/pandas/__init__.py +353 -0
  49. bioagent-bench/.venv/lib/python3.14/site-packages/pandas/_typing.py +578 -0
  50. 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
+ }