BryanW commited on
Commit
3a218ba
·
verified ·
1 Parent(s): bfc723d

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. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__init__.py +239 -0
  2. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/override.py +1 -0
  3. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__init__.py +3 -0
  4. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/main.py +36 -0
  5. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/py.typed +0 -0
  6. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__init__.py +45 -0
  7. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__version__.py +9 -0
  8. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_align.py +25 -0
  9. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_align_getter.py +33 -0
  10. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_base.py +98 -0
  11. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_column.py +352 -0
  12. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_common.py +74 -0
  13. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_container.py +196 -0
  14. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_converter.py +90 -0
  15. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_dataproperty.py +381 -0
  16. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_extractor.py +817 -0
  17. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_formatter.py +98 -0
  18. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_function.py +116 -0
  19. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_interface.py +34 -0
  20. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_line_break.py +8 -0
  21. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_preprocessor.py +173 -0
  22. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/py.typed +0 -0
  23. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/typing.py +63 -0
  24. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/INSTALLER +1 -0
  25. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/LICENSE +35 -0
  26. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/METADATA +280 -0
  27. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/RECORD +97 -0
  28. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/WHEEL +5 -0
  29. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/top_level.txt +1 -0
  30. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/__diff.py +234 -0
  31. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/__info__.py +291 -0
  32. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/__init__.py +119 -0
  33. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/_dill.py +2198 -0
  34. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/_objects.py +537 -0
  35. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/_shims.py +193 -0
  36. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/detect.py +284 -0
  37. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/logger.py +285 -0
  38. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/objtypes.py +24 -0
  39. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/pointers.py +122 -0
  40. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/session.py +613 -0
  41. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/settings.py +25 -0
  42. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/source.py +1017 -0
  43. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/temp.py +252 -0
  44. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__init__.py +51 -0
  45. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/config.py +192 -0
  46. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/hub.py +133 -0
  47. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/info.py +157 -0
  48. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/loading.py +771 -0
  49. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/module.py +1034 -0
  50. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/saving.py +73 -0
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/__init__.py ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # don't import any costly modules
2
+ import os
3
+ import sys
4
+
5
+ report_url = (
6
+ "https://github.com/pypa/setuptools/issues/new?template=distutils-deprecation.yml"
7
+ )
8
+
9
+
10
+ def warn_distutils_present():
11
+ if 'distutils' not in sys.modules:
12
+ return
13
+ import warnings
14
+
15
+ warnings.warn(
16
+ "Distutils was imported before Setuptools, but importing Setuptools "
17
+ "also replaces the `distutils` module in `sys.modules`. This may lead "
18
+ "to undesirable behaviors or errors. To avoid these issues, avoid "
19
+ "using distutils directly, ensure that setuptools is installed in the "
20
+ "traditional way (e.g. not an editable install), and/or make sure "
21
+ "that setuptools is always imported before distutils."
22
+ )
23
+
24
+
25
+ def clear_distutils():
26
+ if 'distutils' not in sys.modules:
27
+ return
28
+ import warnings
29
+
30
+ warnings.warn(
31
+ "Setuptools is replacing distutils. Support for replacing "
32
+ "an already imported distutils is deprecated. In the future, "
33
+ "this condition will fail. "
34
+ f"Register concerns at {report_url}"
35
+ )
36
+ mods = [
37
+ name
38
+ for name in sys.modules
39
+ if name == "distutils" or name.startswith("distutils.")
40
+ ]
41
+ for name in mods:
42
+ del sys.modules[name]
43
+
44
+
45
+ def enabled():
46
+ """
47
+ Allow selection of distutils by environment variable.
48
+ """
49
+ which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local')
50
+ if which == 'stdlib':
51
+ import warnings
52
+
53
+ warnings.warn(
54
+ "Reliance on distutils from stdlib is deprecated. Users "
55
+ "must rely on setuptools to provide the distutils module. "
56
+ "Avoid importing distutils or import setuptools first, "
57
+ "and avoid setting SETUPTOOLS_USE_DISTUTILS=stdlib. "
58
+ f"Register concerns at {report_url}"
59
+ )
60
+ return which == 'local'
61
+
62
+
63
+ def ensure_local_distutils():
64
+ import importlib
65
+
66
+ clear_distutils()
67
+
68
+ # With the DistutilsMetaFinder in place,
69
+ # perform an import to cause distutils to be
70
+ # loaded from setuptools._distutils. Ref #2906.
71
+ with shim():
72
+ importlib.import_module('distutils')
73
+
74
+ # check that submodules load as expected
75
+ core = importlib.import_module('distutils.core')
76
+ assert '_distutils' in core.__file__, core.__file__
77
+ assert 'setuptools._distutils.log' not in sys.modules
78
+
79
+
80
+ def do_override():
81
+ """
82
+ Ensure that the local copy of distutils is preferred over stdlib.
83
+
84
+ See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401
85
+ for more motivation.
86
+ """
87
+ if enabled():
88
+ warn_distutils_present()
89
+ ensure_local_distutils()
90
+
91
+
92
+ class _TrivialRe:
93
+ def __init__(self, *patterns) -> None:
94
+ self._patterns = patterns
95
+
96
+ def match(self, string):
97
+ return all(pat in string for pat in self._patterns)
98
+
99
+
100
+ class DistutilsMetaFinder:
101
+ def find_spec(self, fullname, path, target=None):
102
+ # optimization: only consider top level modules and those
103
+ # found in the CPython test suite.
104
+ if path is not None and not fullname.startswith('test.'):
105
+ return None
106
+
107
+ method_name = 'spec_for_{fullname}'.format(**locals())
108
+ method = getattr(self, method_name, lambda: None)
109
+ return method()
110
+
111
+ def spec_for_distutils(self):
112
+ if self.is_cpython():
113
+ return None
114
+
115
+ import importlib
116
+ import importlib.abc
117
+ import importlib.util
118
+
119
+ try:
120
+ mod = importlib.import_module('setuptools._distutils')
121
+ except Exception:
122
+ # There are a couple of cases where setuptools._distutils
123
+ # may not be present:
124
+ # - An older Setuptools without a local distutils is
125
+ # taking precedence. Ref #2957.
126
+ # - Path manipulation during sitecustomize removes
127
+ # setuptools from the path but only after the hook
128
+ # has been loaded. Ref #2980.
129
+ # In either case, fall back to stdlib behavior.
130
+ return None
131
+
132
+ class DistutilsLoader(importlib.abc.Loader):
133
+ def create_module(self, spec):
134
+ mod.__name__ = 'distutils'
135
+ return mod
136
+
137
+ def exec_module(self, module):
138
+ pass
139
+
140
+ return importlib.util.spec_from_loader(
141
+ 'distutils', DistutilsLoader(), origin=mod.__file__
142
+ )
143
+
144
+ @staticmethod
145
+ def is_cpython():
146
+ """
147
+ Suppress supplying distutils for CPython (build and tests).
148
+ Ref #2965 and #3007.
149
+ """
150
+ return os.path.isfile('pybuilddir.txt')
151
+
152
+ def spec_for_pip(self):
153
+ """
154
+ Ensure stdlib distutils when running under pip.
155
+ See pypa/pip#8761 for rationale.
156
+ """
157
+ if sys.version_info >= (3, 12) or self.pip_imported_during_build():
158
+ return
159
+ clear_distutils()
160
+ self.spec_for_distutils = lambda: None
161
+
162
+ @classmethod
163
+ def pip_imported_during_build(cls):
164
+ """
165
+ Detect if pip is being imported in a build script. Ref #2355.
166
+ """
167
+ import traceback
168
+
169
+ return any(
170
+ cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None)
171
+ )
172
+
173
+ @staticmethod
174
+ def frame_file_is_setup(frame):
175
+ """
176
+ Return True if the indicated frame suggests a setup.py file.
177
+ """
178
+ # some frames may not have __file__ (#2940)
179
+ return frame.f_globals.get('__file__', '').endswith('setup.py')
180
+
181
+ def spec_for_sensitive_tests(self):
182
+ """
183
+ Ensure stdlib distutils when running select tests under CPython.
184
+
185
+ python/cpython#91169
186
+ """
187
+ clear_distutils()
188
+ self.spec_for_distutils = lambda: None
189
+
190
+ sensitive_tests = (
191
+ [
192
+ 'test.test_distutils',
193
+ 'test.test_peg_generator',
194
+ 'test.test_importlib',
195
+ ]
196
+ if sys.version_info < (3, 10)
197
+ else [
198
+ 'test.test_distutils',
199
+ ]
200
+ )
201
+
202
+
203
+ for name in DistutilsMetaFinder.sensitive_tests:
204
+ setattr(
205
+ DistutilsMetaFinder,
206
+ f'spec_for_{name}',
207
+ DistutilsMetaFinder.spec_for_sensitive_tests,
208
+ )
209
+
210
+
211
+ DISTUTILS_FINDER = DistutilsMetaFinder()
212
+
213
+
214
+ def add_shim():
215
+ DISTUTILS_FINDER in sys.meta_path or insert_shim()
216
+
217
+
218
+ class shim:
219
+ def __enter__(self) -> None:
220
+ insert_shim()
221
+
222
+ def __exit__(self, exc: object, value: object, tb: object) -> None:
223
+ _remove_shim()
224
+
225
+
226
+ def insert_shim():
227
+ sys.meta_path.insert(0, DISTUTILS_FINDER)
228
+
229
+
230
+ def _remove_shim():
231
+ try:
232
+ sys.meta_path.remove(DISTUTILS_FINDER)
233
+ except ValueError:
234
+ pass
235
+
236
+
237
+ if sys.version_info < (3, 12):
238
+ # DistutilsMetaFinder can only be disabled in Python < 3.12 (PEP 632)
239
+ remove_shim = _remove_shim
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/_distutils_hack/override.py ADDED
@@ -0,0 +1 @@
 
 
1
+ __import__('_distutils_hack').do_override()
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .main import Doc as Doc
2
+
3
+ __version__ = "0.0.4"
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/main.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class Doc:
2
+ """Define the documentation of a type annotation using `Annotated`, to be
3
+ used in class attributes, function and method parameters, return values,
4
+ and variables.
5
+
6
+ The value should be a positional-only string literal to allow static tools
7
+ like editors and documentation generators to use it.
8
+
9
+ This complements docstrings.
10
+
11
+ The string value passed is available in the attribute `documentation`.
12
+
13
+ Example:
14
+
15
+ ```Python
16
+ from typing import Annotated
17
+ from annotated_doc import Doc
18
+
19
+ def hi(name: Annotated[str, Doc("Who to say hi to")]) -> None:
20
+ print(f"Hi, {name}!")
21
+ ```
22
+ """
23
+
24
+ def __init__(self, documentation: str, /) -> None:
25
+ self.documentation = documentation
26
+
27
+ def __repr__(self) -> str:
28
+ return f"Doc({self.documentation!r})"
29
+
30
+ def __hash__(self) -> int:
31
+ return hash(self.documentation)
32
+
33
+ def __eq__(self, other: object) -> bool:
34
+ if not isinstance(other, Doc):
35
+ return NotImplemented
36
+ return self.documentation == other.documentation
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/annotated_doc/py.typed ADDED
File without changes
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__init__.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ from .__version__ import __author__, __copyright__, __email__, __license__, __version__
6
+ from ._align import Align
7
+ from ._align_getter import align_getter
8
+ from ._column import ColumnDataProperty
9
+ from ._common import MAX_STRICT_LEVEL_MAP, MIN_STRICT_LEVEL_MAP, NOT_QUOTING_FLAGS, DefaultValue
10
+ from ._container import MinMaxContainer
11
+ from ._dataproperty import DataProperty
12
+ from ._extractor import DataPropertyExtractor, DataPropertyMatrix, MatrixFormatting
13
+ from ._formatter import Format
14
+ from ._function import calc_ascii_char_width, get_integer_digit, get_number_of_digit
15
+ from ._line_break import LineBreakHandling
16
+ from ._preprocessor import Preprocessor
17
+ from .logger import set_logger
18
+
19
+
20
+ __all__ = (
21
+ "Align",
22
+ "align_getter",
23
+ "ColumnDataProperty",
24
+ "DataProperty",
25
+ "DataPropertyExtractor",
26
+ "DataPropertyMatrix",
27
+ "Format",
28
+ "LineBreakHandling",
29
+ "MatrixFormatting",
30
+ "MinMaxContainer",
31
+ "Preprocessor",
32
+ "calc_ascii_char_width",
33
+ "get_integer_digit",
34
+ "get_number_of_digit",
35
+ "MAX_STRICT_LEVEL_MAP",
36
+ "MIN_STRICT_LEVEL_MAP",
37
+ "NOT_QUOTING_FLAGS",
38
+ "DefaultValue",
39
+ "set_logger",
40
+ "__author__",
41
+ "__copyright__",
42
+ "__email__",
43
+ "__license__",
44
+ "__version__",
45
+ )
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/__version__.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Final
2
+
3
+
4
+ __author__: Final = "Tsuyoshi Hombashi"
5
+ __copyright__: Final = f"Copyright 2016-2024, {__author__}"
6
+ __license__: Final = "MIT License"
7
+ __version__ = "1.1.0"
8
+ __maintainer__: Final = __author__
9
+ __email__: Final = "tsuyoshi.hombashi@gmail.com"
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_align.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ import enum
6
+
7
+
8
+ @enum.unique
9
+ class Align(enum.Enum):
10
+ AUTO = (1 << 0, "auto")
11
+ LEFT = (1 << 1, "left")
12
+ RIGHT = (1 << 2, "right")
13
+ CENTER = (1 << 3, "center")
14
+
15
+ @property
16
+ def align_code(self) -> int:
17
+ return self.__align_code
18
+
19
+ @property
20
+ def align_string(self) -> str:
21
+ return self.__align_string
22
+
23
+ def __init__(self, code: int, string: str) -> None:
24
+ self.__align_code = code
25
+ self.__align_string = string
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_align_getter.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ from typing import Dict
6
+
7
+ from typepy import Typecode
8
+
9
+ from ._align import Align
10
+
11
+
12
+ class AlignGetter:
13
+ @property
14
+ def typecode_align_table(self):
15
+ raise NotImplementedError()
16
+
17
+ @typecode_align_table.setter
18
+ def typecode_align_table(self, x: Dict[Typecode, Align]) -> None:
19
+ self.__typecode_align_table = x
20
+
21
+ def get_align_from_typecode(self, typecode: Typecode) -> Align:
22
+ return self.__typecode_align_table.get(typecode, self.default_align)
23
+
24
+ def __init__(self) -> None:
25
+ self.typecode_align_table = {
26
+ Typecode.STRING: Align.LEFT,
27
+ Typecode.INTEGER: Align.RIGHT,
28
+ Typecode.REAL_NUMBER: Align.RIGHT,
29
+ }
30
+ self.default_align = Align.LEFT
31
+
32
+
33
+ align_getter = AlignGetter()
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_base.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Final, Optional
2
+
3
+ from typepy import (
4
+ Bool,
5
+ DateTime,
6
+ Dictionary,
7
+ Infinity,
8
+ Integer,
9
+ IpAddress,
10
+ List,
11
+ Nan,
12
+ NoneType,
13
+ NullString,
14
+ RealNumber,
15
+ String,
16
+ Typecode,
17
+ )
18
+ from typepy.type import AbstractType
19
+
20
+ from ._formatter import Formatter
21
+ from ._interface import DataPeropertyInterface
22
+
23
+
24
+ class DataPeropertyBase(DataPeropertyInterface):
25
+ __slots__ = (
26
+ "_datetime_format_str",
27
+ "_decimal_places",
28
+ "_east_asian_ambiguous_width",
29
+ "_formatter",
30
+ "_typecode",
31
+ "__format_str",
32
+ )
33
+
34
+ __TYPE_CLASS_TABLE: Final[dict[Typecode, type[AbstractType]]] = {
35
+ Typecode.BOOL: Bool,
36
+ Typecode.DATETIME: DateTime,
37
+ Typecode.DICTIONARY: Dictionary,
38
+ Typecode.INTEGER: Integer,
39
+ Typecode.INFINITY: Infinity,
40
+ Typecode.IP_ADDRESS: IpAddress,
41
+ Typecode.LIST: List,
42
+ Typecode.NAN: Nan,
43
+ Typecode.NONE: NoneType,
44
+ Typecode.NULL_STRING: NullString,
45
+ Typecode.REAL_NUMBER: RealNumber,
46
+ Typecode.STRING: String,
47
+ }
48
+
49
+ @property
50
+ def type_class(self) -> type[AbstractType]:
51
+ return self.__TYPE_CLASS_TABLE[self.typecode]
52
+
53
+ @property
54
+ def typecode(self) -> Typecode:
55
+ """
56
+ ``typepy.Typecode`` that corresponds to the type of the ``data``.
57
+
58
+ :return:
59
+ One of the Enum value that are defined ``typepy.Typecode``.
60
+ :rtype: typepy.Typecode
61
+ """
62
+
63
+ assert self._typecode
64
+
65
+ return self._typecode
66
+
67
+ @property
68
+ def typename(self) -> str:
69
+ return self.typecode.name
70
+
71
+ def __init__(
72
+ self,
73
+ format_flags: Optional[int],
74
+ is_formatting_float: bool,
75
+ datetime_format_str: str,
76
+ east_asian_ambiguous_width: int,
77
+ ) -> None:
78
+ self._decimal_places: Optional[int] = None
79
+ self._east_asian_ambiguous_width = east_asian_ambiguous_width
80
+ self._typecode: Optional[Typecode] = None
81
+
82
+ self._datetime_format_str = datetime_format_str
83
+ self.__format_str = ""
84
+
85
+ self._formatter = Formatter(
86
+ format_flags=format_flags,
87
+ datetime_format_str=self._datetime_format_str,
88
+ is_formatting_float=is_formatting_float,
89
+ )
90
+
91
+ @property
92
+ def format_str(self) -> str:
93
+ if self.__format_str:
94
+ return self.__format_str
95
+
96
+ self.__format_str = self._formatter.make_format_str(self.typecode, self.decimal_places)
97
+
98
+ return self.__format_str
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_column.py ADDED
@@ -0,0 +1,352 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Optional
2
+
3
+ from mbstrdecoder import MultiByteStrDecoder
4
+ from typepy import Integer, StrictLevel, Typecode, TypeConversionError
5
+
6
+ from ._align import Align
7
+ from ._align_getter import align_getter
8
+ from ._base import DataPeropertyBase
9
+ from ._common import DefaultValue
10
+ from ._container import ListContainer, MinMaxContainer
11
+ from ._dataproperty import DataProperty
12
+ from ._function import calc_ascii_char_width
13
+ from .typing import FloatType
14
+
15
+
16
+ class ColumnDataProperty(DataPeropertyBase):
17
+ __slots__ = (
18
+ "__header_ascii_char_width",
19
+ "__body_ascii_char_width",
20
+ "__column_index",
21
+ "__dp_list",
22
+ "__float_type",
23
+ "__format_map",
24
+ "__is_calculate",
25
+ "__max_precision",
26
+ "__minmax_integer_digits",
27
+ "__minmax_decimal_places",
28
+ "__minmax_additional_format_len",
29
+ "__typecode_bitmap",
30
+ )
31
+
32
+ @property
33
+ def align(self) -> Align:
34
+ return align_getter.get_align_from_typecode(self.typecode)
35
+
36
+ @property
37
+ def bit_length(self) -> Optional[int]:
38
+ if self.typecode != Typecode.INTEGER:
39
+ return None
40
+
41
+ bit_length = 0
42
+ for value_dp in self.__dp_list:
43
+ try:
44
+ bit_length = max(bit_length, int.bit_length(value_dp.data))
45
+ except TypeError:
46
+ pass
47
+
48
+ return bit_length
49
+
50
+ @property
51
+ def column_index(self) -> int:
52
+ return self.__column_index
53
+
54
+ @property
55
+ def decimal_places(self) -> Optional[int]:
56
+ return self._decimal_places
57
+
58
+ @property
59
+ def ascii_char_width(self) -> int:
60
+ return max(self.__header_ascii_char_width, self.__body_ascii_char_width)
61
+
62
+ @property
63
+ def minmax_integer_digits(self) -> MinMaxContainer:
64
+ return self.__minmax_integer_digits
65
+
66
+ @property
67
+ def minmax_decimal_places(self) -> ListContainer:
68
+ return self.__minmax_decimal_places
69
+
70
+ @property
71
+ def minmax_additional_format_len(self) -> MinMaxContainer:
72
+ return self.__minmax_additional_format_len
73
+
74
+ def __init__(
75
+ self,
76
+ column_index: int,
77
+ float_type: Optional[FloatType],
78
+ min_width: int = 0,
79
+ format_flags: Optional[int] = None,
80
+ is_formatting_float: bool = True,
81
+ datetime_format_str: str = DefaultValue.DATETIME_FORMAT,
82
+ east_asian_ambiguous_width: int = 1,
83
+ max_precision: int = DefaultValue.MAX_PRECISION,
84
+ ) -> None:
85
+ super().__init__(
86
+ format_flags=format_flags,
87
+ is_formatting_float=is_formatting_float,
88
+ datetime_format_str=datetime_format_str,
89
+ east_asian_ambiguous_width=east_asian_ambiguous_width,
90
+ )
91
+
92
+ self.__header_ascii_char_width = 0
93
+ self.__body_ascii_char_width = min_width
94
+ self.__column_index = column_index
95
+
96
+ self.__float_type = float_type
97
+
98
+ self.__is_calculate = True
99
+ self.__dp_list: list[DataProperty] = []
100
+ self.__minmax_integer_digits = MinMaxContainer()
101
+ self.__minmax_decimal_places = ListContainer()
102
+ self.__minmax_additional_format_len = MinMaxContainer()
103
+ self.__max_precision = max_precision
104
+
105
+ self.__typecode_bitmap = Typecode.NONE.value
106
+ self.__calc_typecode_from_bitmap()
107
+
108
+ self.__format_map: dict[Typecode, str] = self._formatter.make_format_map(
109
+ decimal_places=self._decimal_places
110
+ )
111
+
112
+ def __repr__(self) -> str:
113
+ element_list = []
114
+
115
+ if self.column_index is not None:
116
+ element_list.append(f"column={self.column_index}")
117
+
118
+ element_list.extend(
119
+ [
120
+ f"type={self.typename}",
121
+ f"align={self.align.align_string}",
122
+ f"ascii_width={self.ascii_char_width}",
123
+ ]
124
+ )
125
+
126
+ if Integer(self.bit_length).is_type():
127
+ element_list.append(f"bit_len={self.bit_length}")
128
+
129
+ if self.minmax_integer_digits.has_value():
130
+ if self.minmax_integer_digits.is_same_value():
131
+ value = f"int_digits={self.minmax_integer_digits.min_value}"
132
+ else:
133
+ value = f"int_digits=({self.minmax_integer_digits})"
134
+
135
+ element_list.append(value)
136
+
137
+ if self.minmax_decimal_places.has_value():
138
+ if self.minmax_decimal_places.is_same_value():
139
+ value = f"decimal_places={self.minmax_decimal_places.min_value}"
140
+ else:
141
+ value = f"decimal_places=({self.minmax_decimal_places})"
142
+
143
+ element_list.append(value)
144
+
145
+ if not self.minmax_additional_format_len.is_zero():
146
+ if self.minmax_additional_format_len.is_same_value():
147
+ value = f"extra_len={self.minmax_additional_format_len.min_value}"
148
+ else:
149
+ value = f"extra_len=({self.minmax_additional_format_len})"
150
+
151
+ element_list.append(value)
152
+
153
+ return ", ".join(element_list)
154
+
155
+ def dp_to_str(self, value_dp: DataProperty) -> str:
156
+ if value_dp.typecode == Typecode.STRING:
157
+ return str(value_dp.data)
158
+
159
+ try:
160
+ value = self.__preprocess_value_before_tostring(value_dp)
161
+ except TypeConversionError:
162
+ return self.__format_map.get(value_dp.typecode, "{:s}").format(value_dp.data)
163
+
164
+ to_string_format_str = self.__get_tostring_format(value_dp)
165
+
166
+ try:
167
+ return to_string_format_str.format(value)
168
+ except (ValueError, TypeError):
169
+ pass
170
+
171
+ try:
172
+ return MultiByteStrDecoder(value).unicode_str
173
+ except ValueError:
174
+ pass
175
+
176
+ return str(value)
177
+
178
+ def extend_width(self, ascii_char_width: int) -> None:
179
+ self.extend_header_width(ascii_char_width)
180
+ self.extend_body_width(ascii_char_width)
181
+
182
+ def extend_header_width(self, ascii_char_width: int) -> None:
183
+ self.__header_ascii_char_width += ascii_char_width
184
+
185
+ def extend_body_width(self, ascii_char_width: int) -> None:
186
+ self.__body_ascii_char_width += ascii_char_width
187
+
188
+ def update_header(self, header_db: DataProperty) -> None:
189
+ self.__header_ascii_char_width = header_db.ascii_char_width
190
+
191
+ def update_body(self, value_dp: DataProperty) -> None:
192
+ if value_dp.is_include_ansi_escape:
193
+ assert value_dp.no_ansi_escape_dp
194
+ value_dp = value_dp.no_ansi_escape_dp
195
+
196
+ self.__typecode_bitmap |= value_dp.typecode.value
197
+ self.__calc_typecode_from_bitmap()
198
+
199
+ if value_dp.typecode in (Typecode.REAL_NUMBER, Typecode.INTEGER):
200
+ self.__minmax_integer_digits.update(value_dp.integer_digits)
201
+ self.__minmax_decimal_places.update(value_dp.decimal_places)
202
+ self.__update_decimal_places()
203
+
204
+ self.__minmax_additional_format_len.update(value_dp.additional_format_len)
205
+
206
+ self.__dp_list.append(value_dp)
207
+ self.__update_ascii_char_width()
208
+
209
+ def merge(self, column_dp: "ColumnDataProperty") -> None:
210
+ self.__typecode_bitmap |= column_dp.typecode.value
211
+ self.__calc_typecode_from_bitmap()
212
+
213
+ self.__minmax_integer_digits.merge(column_dp.minmax_integer_digits)
214
+ self.__minmax_decimal_places.merge(column_dp.minmax_decimal_places)
215
+ self.__update_decimal_places()
216
+
217
+ self.__minmax_additional_format_len.merge(column_dp.minmax_additional_format_len)
218
+
219
+ self.__body_ascii_char_width = max(self.__body_ascii_char_width, column_dp.ascii_char_width)
220
+ self.__update_ascii_char_width()
221
+
222
+ def begin_update(self) -> None:
223
+ self.__is_calculate = False
224
+
225
+ def end_update(self) -> None:
226
+ self.__is_calculate = True
227
+
228
+ self.__calc_typecode_from_bitmap()
229
+ self.__update_decimal_places()
230
+ self.__update_ascii_char_width()
231
+
232
+ def __is_not_single_typecode(self, typecode_bitmap: int) -> bool:
233
+ return bool(
234
+ self.__typecode_bitmap & typecode_bitmap and self.__typecode_bitmap & ~typecode_bitmap
235
+ )
236
+
237
+ def __is_float_typecode(self) -> bool:
238
+ FLOAT_TYPECODE_BMP = (
239
+ Typecode.REAL_NUMBER.value | Typecode.INFINITY.value | Typecode.NAN.value
240
+ )
241
+ NUMBER_TYPECODE_BMP = FLOAT_TYPECODE_BMP | Typecode.INTEGER.value
242
+
243
+ if self.__is_not_single_typecode(NUMBER_TYPECODE_BMP | Typecode.NULL_STRING.value):
244
+ return False
245
+
246
+ if (
247
+ bin(self.__typecode_bitmap & (FLOAT_TYPECODE_BMP | Typecode.NULL_STRING.value)).count(
248
+ "1"
249
+ )
250
+ >= 2
251
+ ):
252
+ return True
253
+
254
+ if bin(self.__typecode_bitmap & NUMBER_TYPECODE_BMP).count("1") >= 2:
255
+ return True
256
+
257
+ return False
258
+
259
+ def __calc_body_ascii_char_width(self) -> int:
260
+ width_list = [self.__body_ascii_char_width]
261
+
262
+ for value_dp in self.__dp_list:
263
+ if value_dp.is_include_ansi_escape:
264
+ assert value_dp.no_ansi_escape_dp
265
+ value_dp = value_dp.no_ansi_escape_dp
266
+
267
+ width_list.append(
268
+ calc_ascii_char_width(self.dp_to_str(value_dp), self._east_asian_ambiguous_width)
269
+ )
270
+
271
+ return max(width_list)
272
+
273
+ def __calc_decimal_places(self) -> Optional[int]:
274
+ if self.minmax_decimal_places.max_value is None:
275
+ return None
276
+
277
+ return min(self.__max_precision, int(self.minmax_decimal_places.max_value))
278
+
279
+ def __get_tostring_format(self, value_dp: DataProperty) -> str:
280
+ if self.typecode == Typecode.STRING:
281
+ return self.__format_map.get(value_dp.typecode, "{:s}")
282
+
283
+ return self.__format_map.get(self.typecode, "{:s}")
284
+
285
+ def __get_typecode_from_bitmap(self) -> Typecode:
286
+ if self.__is_float_typecode():
287
+ return Typecode.REAL_NUMBER
288
+
289
+ if any(
290
+ [
291
+ self.__is_not_single_typecode(Typecode.BOOL.value),
292
+ self.__is_not_single_typecode(Typecode.DATETIME.value),
293
+ ]
294
+ ):
295
+ return Typecode.STRING
296
+
297
+ typecode_list = [
298
+ Typecode.STRING,
299
+ Typecode.REAL_NUMBER,
300
+ Typecode.INTEGER,
301
+ Typecode.DATETIME,
302
+ Typecode.DICTIONARY,
303
+ Typecode.IP_ADDRESS,
304
+ Typecode.LIST,
305
+ Typecode.BOOL,
306
+ Typecode.INFINITY,
307
+ Typecode.NAN,
308
+ Typecode.NULL_STRING,
309
+ ]
310
+
311
+ for typecode in typecode_list:
312
+ if self.__typecode_bitmap & typecode.value:
313
+ return typecode
314
+
315
+ if self.__typecode_bitmap == Typecode.NONE.value:
316
+ return Typecode.NONE
317
+
318
+ return Typecode.STRING
319
+
320
+ def __update_ascii_char_width(self) -> None:
321
+ if not self.__is_calculate:
322
+ return
323
+
324
+ self.__body_ascii_char_width = self.__calc_body_ascii_char_width()
325
+
326
+ def __update_decimal_places(self) -> None:
327
+ if not self.__is_calculate:
328
+ return
329
+
330
+ self._decimal_places = self.__calc_decimal_places()
331
+ self.__format_map = self._formatter.make_format_map(decimal_places=self._decimal_places)
332
+
333
+ def __calc_typecode_from_bitmap(self) -> None:
334
+ if not self.__is_calculate:
335
+ return
336
+
337
+ self._typecode = self.__get_typecode_from_bitmap()
338
+
339
+ def __preprocess_value_before_tostring(self, value_dp: DataProperty) -> Any:
340
+ if self.typecode == value_dp.typecode or self.typecode in [
341
+ Typecode.STRING,
342
+ Typecode.BOOL,
343
+ Typecode.DATETIME,
344
+ ]:
345
+ return value_dp.data
346
+
347
+ return self.type_class(
348
+ value_dp.data,
349
+ strict_level=StrictLevel.MIN,
350
+ float_type=self.__float_type,
351
+ strip_ansi_escape=False,
352
+ ).convert()
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_common.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ import copy
6
+ import itertools
7
+ from datetime import datetime
8
+ from decimal import Decimal
9
+ from typing import Final
10
+
11
+ from typepy import StrictLevel, Typecode
12
+
13
+ from .typing import StrictLevelMap, TypeValueMap
14
+
15
+
16
+ NOT_QUOTING_FLAGS: Final = {
17
+ Typecode.BOOL: False,
18
+ Typecode.DATETIME: False,
19
+ Typecode.DICTIONARY: False,
20
+ Typecode.INFINITY: False,
21
+ Typecode.INTEGER: False,
22
+ Typecode.IP_ADDRESS: False,
23
+ Typecode.LIST: False,
24
+ Typecode.NAN: False,
25
+ Typecode.NULL_STRING: False,
26
+ Typecode.NONE: False,
27
+ Typecode.REAL_NUMBER: False,
28
+ Typecode.STRING: False,
29
+ }
30
+
31
+ MAX_STRICT_LEVEL_MAP: Final[StrictLevelMap] = dict(
32
+ itertools.product(list(Typecode), [StrictLevel.MAX])
33
+ )
34
+ MIN_STRICT_LEVEL_MAP: Final[StrictLevelMap] = dict(
35
+ itertools.product(list(Typecode), [StrictLevel.MIN])
36
+ )
37
+
38
+
39
+ class DefaultValue:
40
+ DATETIME_FORMAT: Final = "%Y-%m-%dT%H:%M:%S%z"
41
+ FLOAT_TYPE: Final = Decimal
42
+ INF_VALUE: Final = FLOAT_TYPE("inf")
43
+ NAN_VALUE: Final = FLOAT_TYPE("nan")
44
+
45
+ QUOTING_FLAGS: Final = copy.deepcopy(NOT_QUOTING_FLAGS)
46
+
47
+ STRICT_LEVEL_MAP: Final[StrictLevelMap] = {
48
+ "default": StrictLevel.MAX,
49
+ Typecode.BOOL: StrictLevel.MAX,
50
+ Typecode.DATETIME: StrictLevel.MAX,
51
+ Typecode.DICTIONARY: StrictLevel.MAX,
52
+ Typecode.REAL_NUMBER: 1,
53
+ Typecode.INFINITY: StrictLevel.MIN,
54
+ Typecode.INTEGER: 1,
55
+ Typecode.IP_ADDRESS: StrictLevel.MAX,
56
+ Typecode.LIST: StrictLevel.MAX,
57
+ Typecode.NAN: StrictLevel.MIN,
58
+ Typecode.NONE: StrictLevel.MAX,
59
+ Typecode.NULL_STRING: StrictLevel.MIN,
60
+ Typecode.STRING: StrictLevel.MIN,
61
+ }
62
+
63
+ TYPE_VALUE_MAP: Final[TypeValueMap] = {
64
+ Typecode.NONE: None,
65
+ Typecode.INFINITY: INF_VALUE,
66
+ Typecode.NAN: NAN_VALUE,
67
+ }
68
+
69
+ MAX_WORKERS: Final = 1
70
+ MAX_PRECISION: Final = 100
71
+
72
+
73
+ def default_datetime_formatter(value: datetime) -> str:
74
+ return value.strftime(DefaultValue.DATETIME_FORMAT)
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_container.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ import abc
6
+ from collections.abc import Sequence
7
+ from decimal import Decimal
8
+ from typing import Any, Final, Optional, Union
9
+
10
+ from typepy import RealNumber
11
+
12
+
13
+ T = Union[int, float, Decimal]
14
+ NAN: Final = Decimal("nan")
15
+
16
+
17
+ class AbstractContainer(metaclass=abc.ABCMeta):
18
+ @property
19
+ @abc.abstractmethod
20
+ def min_value(self) -> Optional[Decimal]: # pragma: no cover
21
+ pass
22
+
23
+ @property
24
+ @abc.abstractmethod
25
+ def max_value(self) -> Optional[Decimal]: # pragma: no cover
26
+ pass
27
+
28
+ @abc.abstractmethod
29
+ def mean(self) -> Decimal: # pragma: no cover
30
+ pass
31
+
32
+ @abc.abstractmethod
33
+ def update(self, value: Optional[T]) -> None: # pragma: no cover
34
+ pass
35
+
36
+ @abc.abstractmethod
37
+ def merge(self, value: "AbstractContainer") -> None: # pragma: no cover
38
+ pass
39
+
40
+ def __repr__(self) -> str:
41
+ if not self.has_value():
42
+ return "None"
43
+
44
+ return ", ".join([f"min={self.min_value}", f"max={self.max_value}"])
45
+
46
+ def has_value(self) -> bool:
47
+ return self.min_value is not None and self.max_value is not None
48
+
49
+ def is_same_value(self) -> bool:
50
+ return self.has_value() and self.min_value == self.max_value
51
+
52
+ def is_zero(self) -> bool:
53
+ return self.has_value() and self.min_value == 0 and self.max_value == 0
54
+
55
+
56
+ class ListContainer(AbstractContainer):
57
+ __slots__ = ("__value_list",)
58
+
59
+ @property
60
+ def min_value(self) -> Optional[Decimal]:
61
+ try:
62
+ return min(self.__value_list)
63
+ except ValueError:
64
+ return None
65
+
66
+ @property
67
+ def max_value(self) -> Optional[Decimal]:
68
+ try:
69
+ return max(self.__value_list)
70
+ except ValueError:
71
+ return None
72
+
73
+ @property
74
+ def value_list(self) -> list[Decimal]:
75
+ return self.__value_list
76
+
77
+ def __init__(self, value_list: Optional[list[Decimal]] = None) -> None:
78
+ if value_list is None:
79
+ self.__value_list: list[Decimal] = []
80
+ return
81
+
82
+ for value in value_list:
83
+ self.update(value)
84
+
85
+ def mean(self) -> Decimal:
86
+ try:
87
+ return Decimal(sum(self.__value_list) / len(self.__value_list))
88
+ except ZeroDivisionError:
89
+ return NAN
90
+
91
+ def update(self, value: Union[int, float, Decimal, None]) -> None:
92
+ if value is None:
93
+ return
94
+
95
+ store_value = RealNumber(value).try_convert()
96
+ if store_value is None:
97
+ return
98
+
99
+ self.__value_list.append(store_value)
100
+
101
+ def merge(self, value: "AbstractContainer") -> None:
102
+ if not isinstance(value, ListContainer):
103
+ return
104
+
105
+ for v in value.value_list:
106
+ self.update(v)
107
+
108
+
109
+ class MinMaxContainer(AbstractContainer):
110
+ __slots__ = ("__min_value", "__max_value")
111
+
112
+ def __init__(self, value_list: Optional[Sequence[Decimal]] = None) -> None:
113
+ self.__min_value: Optional[Decimal] = None
114
+ self.__max_value: Optional[Decimal] = None
115
+
116
+ if value_list is None:
117
+ return
118
+
119
+ for value in value_list:
120
+ self.update(value)
121
+
122
+ @property
123
+ def min_value(self) -> Optional[Decimal]:
124
+ return self.__min_value
125
+
126
+ @property
127
+ def max_value(self) -> Optional[Decimal]:
128
+ return self.__max_value
129
+
130
+ def __eq__(self, other: Any) -> bool:
131
+ if not isinstance(other, MinMaxContainer):
132
+ return False
133
+
134
+ return all([self.min_value == other.min_value, self.max_value == other.max_value])
135
+
136
+ def __ne__(self, other: Any) -> bool:
137
+ if not isinstance(other, MinMaxContainer):
138
+ return True
139
+
140
+ return any([self.min_value != other.min_value, self.max_value != other.max_value])
141
+
142
+ def __contains__(self, x: T) -> bool:
143
+ if self.min_value is None:
144
+ return False
145
+
146
+ if self.max_value is None:
147
+ return False
148
+
149
+ return self.min_value <= x <= self.max_value
150
+
151
+ def diff(self) -> Decimal:
152
+ if self.min_value is None:
153
+ return NAN
154
+
155
+ if self.max_value is None:
156
+ return NAN
157
+
158
+ try:
159
+ return self.max_value - self.min_value
160
+ except TypeError:
161
+ return NAN
162
+
163
+ def mean(self) -> Decimal:
164
+ if self.min_value is None:
165
+ return NAN
166
+
167
+ if self.max_value is None:
168
+ return NAN
169
+
170
+ try:
171
+ return (self.max_value + self.min_value) * Decimal("0.5")
172
+ except TypeError:
173
+ return NAN
174
+
175
+ def update(self, value: Optional[T]) -> None:
176
+ if value is None:
177
+ return
178
+
179
+ decimal_value = Decimal(value)
180
+
181
+ if self.__min_value is None:
182
+ self.__min_value = decimal_value
183
+ else:
184
+ self.__min_value = min(self.__min_value, decimal_value)
185
+
186
+ if self.__max_value is None:
187
+ self.__max_value = decimal_value
188
+ else:
189
+ self.__max_value = max(self.__max_value, decimal_value)
190
+
191
+ def merge(self, value: "AbstractContainer") -> None:
192
+ if not isinstance(value, MinMaxContainer):
193
+ return
194
+
195
+ self.update(value.min_value)
196
+ self.update(value.max_value)
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_converter.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ import re
6
+ from typing import Any, Final, Optional
7
+
8
+ from typepy import Typecode, TypeConversionError
9
+
10
+ from ._common import MAX_STRICT_LEVEL_MAP, DefaultValue
11
+ from ._dataproperty import DataProperty
12
+ from ._preprocessor import Preprocessor
13
+ from .typing import DateTimeFormatter, FloatType, StrictLevelMap, TypeValueMap
14
+
15
+
16
+ class DataPropertyConverter:
17
+ __RE_QUOTE_LINE: Final = re.compile(r"^\s*[\"'].*[\"']\s*$") # noqa: w605
18
+ __RE_QUOTE_CHAR: Final = re.compile("[\"']")
19
+
20
+ def __init__(
21
+ self,
22
+ preprocessor: Preprocessor,
23
+ datetime_format_str: str,
24
+ datetime_formatter: Optional[DateTimeFormatter] = None,
25
+ type_value_map: Optional[TypeValueMap] = None,
26
+ quoting_flags: Optional[dict[Typecode, bool]] = None,
27
+ float_type: Optional[FloatType] = None,
28
+ strict_level_map: Optional[StrictLevelMap] = None,
29
+ ) -> None:
30
+ self.__preprocessor = preprocessor
31
+ self.__type_value_map: TypeValueMap = (
32
+ type_value_map if type_value_map else DefaultValue.TYPE_VALUE_MAP
33
+ )
34
+ self.__quoting_flags: dict[Typecode, bool] = (
35
+ quoting_flags if quoting_flags else DefaultValue.QUOTING_FLAGS
36
+ )
37
+
38
+ self.__datetime_formatter = datetime_formatter
39
+ self.__datetime_format_str = datetime_format_str
40
+ self.__float_type = float_type
41
+ self.__strict_level_map = strict_level_map
42
+
43
+ def convert(self, dp_value: DataProperty) -> DataProperty:
44
+ try:
45
+ return self.__create_dataproperty(self.__convert_value(dp_value))
46
+ except TypeConversionError:
47
+ pass
48
+
49
+ if not self.__quoting_flags.get(dp_value.typecode):
50
+ if self.__preprocessor.is_escape_html_tag:
51
+ return self.__create_dataproperty(dp_value.to_str())
52
+
53
+ return dp_value
54
+
55
+ return self.__create_dataproperty(self.__apply_quote(dp_value.typecode, dp_value.to_str()))
56
+
57
+ def __create_dataproperty(self, value: Any) -> DataProperty:
58
+ return DataProperty(
59
+ value,
60
+ preprocessor=self.__preprocessor,
61
+ float_type=self.__float_type,
62
+ datetime_format_str=self.__datetime_format_str,
63
+ strict_level_map=MAX_STRICT_LEVEL_MAP,
64
+ )
65
+
66
+ def __apply_quote(self, typecode: Typecode, data: Any) -> Any:
67
+ if not self.__quoting_flags.get(typecode):
68
+ return data
69
+
70
+ try:
71
+ if self.__RE_QUOTE_LINE.search(data):
72
+ return data
73
+ except TypeError:
74
+ return data
75
+
76
+ return '"{}"'.format(self.__RE_QUOTE_CHAR.sub('\\"', data.replace("\\", "\\\\")))
77
+
78
+ def __convert_value(self, dp_value: DataProperty) -> Any:
79
+ if dp_value.typecode in self.__type_value_map:
80
+ return self.__apply_quote(dp_value.typecode, self.__type_value_map[dp_value.typecode])
81
+
82
+ if dp_value.typecode == Typecode.DATETIME and self.__datetime_formatter:
83
+ try:
84
+ return self.__apply_quote(
85
+ dp_value.typecode, self.__datetime_formatter(dp_value.data)
86
+ )
87
+ except TypeError:
88
+ raise TypeConversionError
89
+
90
+ raise TypeConversionError("no need to convert")
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_dataproperty.py ADDED
@@ -0,0 +1,381 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ from decimal import Decimal
6
+ from typing import Any, Final, Optional, cast
7
+
8
+ import typepy
9
+ from mbstrdecoder import MultiByteStrDecoder
10
+ from typepy import (
11
+ Bool,
12
+ DateTime,
13
+ Dictionary,
14
+ Infinity,
15
+ Integer,
16
+ IpAddress,
17
+ Nan,
18
+ NoneType,
19
+ NullString,
20
+ RealNumber,
21
+ StrictLevel,
22
+ String,
23
+ Typecode,
24
+ TypeConversionError,
25
+ )
26
+ from typepy.type import AbstractType
27
+
28
+ from ._align import Align
29
+ from ._align_getter import align_getter
30
+ from ._base import DataPeropertyBase
31
+ from ._common import DefaultValue
32
+ from ._function import calc_ascii_char_width, get_number_of_digit
33
+ from ._preprocessor import Preprocessor
34
+ from .typing import FloatType, StrictLevelMap, TypeHint
35
+
36
+
37
+ class DataProperty(DataPeropertyBase):
38
+ __slots__ = (
39
+ "__data",
40
+ "__no_ansi_escape_data",
41
+ "__align",
42
+ "__integer_digits",
43
+ "__additional_format_len",
44
+ "__length",
45
+ "__ascii_char_width",
46
+ )
47
+
48
+ __type_class_list: Final[list[type[AbstractType]]] = [
49
+ NoneType,
50
+ Integer,
51
+ Infinity,
52
+ Nan,
53
+ IpAddress,
54
+ RealNumber,
55
+ Bool,
56
+ typepy.List,
57
+ Dictionary,
58
+ DateTime,
59
+ NullString,
60
+ String,
61
+ ]
62
+
63
+ def __init__(
64
+ self,
65
+ data: Any,
66
+ preprocessor: Optional[Preprocessor] = None,
67
+ type_hint: TypeHint = None,
68
+ float_type: Optional[FloatType] = None,
69
+ format_flags: Optional[int] = None,
70
+ datetime_format_str: str = DefaultValue.DATETIME_FORMAT,
71
+ strict_level_map: Optional[StrictLevelMap] = None,
72
+ east_asian_ambiguous_width: int = 1,
73
+ ) -> None:
74
+ super().__init__(
75
+ format_flags=format_flags,
76
+ is_formatting_float=True,
77
+ datetime_format_str=datetime_format_str,
78
+ east_asian_ambiguous_width=east_asian_ambiguous_width,
79
+ )
80
+
81
+ self.__additional_format_len: Optional[int] = None
82
+ self.__align: Optional[Align] = None
83
+ self.__ascii_char_width: Optional[int] = None
84
+ self.__integer_digits: Optional[int] = None
85
+ self.__length: Optional[int] = None
86
+
87
+ if preprocessor is None:
88
+ preprocessor = Preprocessor()
89
+
90
+ data, no_ansi_escape_data = preprocessor.preprocess(data)
91
+
92
+ self.__set_data(data, type_hint, float_type, strict_level_map)
93
+
94
+ if no_ansi_escape_data is None or len(data) == len(no_ansi_escape_data):
95
+ self.__no_ansi_escape_data: Optional[DataProperty] = None
96
+ else:
97
+ self.__no_ansi_escape_data = DataProperty(no_ansi_escape_data, float_type=float_type)
98
+
99
+ def __eq__(self, other: Any) -> bool:
100
+ if not isinstance(other, DataProperty):
101
+ return False
102
+
103
+ if self.typecode != other.typecode:
104
+ return False
105
+
106
+ if self.typecode == Typecode.NAN:
107
+ return True
108
+
109
+ return self.data == other.data
110
+
111
+ def __ne__(self, other: Any) -> bool:
112
+ if not isinstance(other, DataProperty):
113
+ return True
114
+
115
+ if self.typecode != other.typecode:
116
+ return True
117
+
118
+ if self.typecode == Typecode.NAN:
119
+ return False
120
+
121
+ return self.data != other.data
122
+
123
+ def __repr__(self) -> str:
124
+ element_list = []
125
+
126
+ if self.typecode == Typecode.DATETIME:
127
+ element_list.append(f"data={str(self.data):s}")
128
+ else:
129
+ try:
130
+ element_list.append("data=" + self.to_str())
131
+ except UnicodeEncodeError:
132
+ element_list.append(f"data={MultiByteStrDecoder(self.data).unicode_str}")
133
+
134
+ element_list.extend(
135
+ [
136
+ f"type={self.typename:s}",
137
+ f"align={self.align.align_string}",
138
+ f"ascii_width={self.ascii_char_width:d}",
139
+ ]
140
+ )
141
+
142
+ if Integer(self.length).is_type():
143
+ element_list.append(f"length={self.length}")
144
+
145
+ if Integer(self.integer_digits).is_type():
146
+ element_list.append(f"int_digits={self.integer_digits}")
147
+
148
+ if Integer(self.decimal_places).is_type():
149
+ element_list.append(f"decimal_places={self.decimal_places}")
150
+
151
+ if Integer(self.additional_format_len).is_type():
152
+ element_list.append(f"extra_len={self.additional_format_len}")
153
+
154
+ return ", ".join(element_list)
155
+
156
+ @property
157
+ def align(self) -> Align:
158
+ if not self.__align:
159
+ if self.is_include_ansi_escape:
160
+ assert self.no_ansi_escape_dp
161
+ self.__align = self.no_ansi_escape_dp.align
162
+ else:
163
+ self.__align = align_getter.get_align_from_typecode(self.typecode)
164
+
165
+ assert self.__align
166
+
167
+ return self.__align
168
+
169
+ @property
170
+ def decimal_places(self) -> Optional[int]:
171
+ """
172
+ :return:
173
+ Decimal places if the ``data`` type either ``float`` or
174
+ ``decimal.Decimal``. Returns ``0`` if the ``data`` type is ``int``.
175
+ Otherwise, returns ``float("nan")``.
176
+ :rtype: int
177
+ """
178
+
179
+ if self._decimal_places is None:
180
+ self.__set_digit()
181
+
182
+ return self._decimal_places
183
+
184
+ @property
185
+ def data(self) -> Any:
186
+ """
187
+ :return: Original data value.
188
+ :rtype: Original data type.
189
+ """
190
+
191
+ return self.__data
192
+
193
+ @property
194
+ def is_include_ansi_escape(self) -> bool:
195
+ if self.no_ansi_escape_dp is None:
196
+ return False
197
+
198
+ return self.length != self.no_ansi_escape_dp.length
199
+
200
+ @property
201
+ def no_ansi_escape_dp(self) -> Optional["DataProperty"]:
202
+ return self.__no_ansi_escape_data
203
+
204
+ @property
205
+ def length(self) -> Optional[int]:
206
+ """
207
+ :return: Length of the ``data``.
208
+ :rtype: int
209
+ """
210
+
211
+ if self.__length is None:
212
+ self.__length = self.__get_length()
213
+
214
+ return self.__length
215
+
216
+ @property
217
+ def ascii_char_width(self) -> int:
218
+ if self.__ascii_char_width is None:
219
+ self.__ascii_char_width = self.__calc_ascii_char_width()
220
+
221
+ return self.__ascii_char_width
222
+
223
+ @property
224
+ def integer_digits(self) -> Optional[int]:
225
+ """
226
+ :return:
227
+ Integer digits if the ``data`` type either
228
+ ``int``/``float``/``decimal.Decimal``.
229
+ Otherwise, returns ``None``.
230
+ :rtype: int
231
+ """
232
+
233
+ if self.__integer_digits is None:
234
+ self.__set_digit()
235
+
236
+ return self.__integer_digits
237
+
238
+ @property
239
+ def additional_format_len(self) -> int:
240
+ if self.__additional_format_len is None:
241
+ self.__additional_format_len = self.__get_additional_format_len()
242
+
243
+ return self.__additional_format_len
244
+
245
+ def get_padding_len(self, ascii_char_width: int) -> int:
246
+ if self.typecode in (Typecode.LIST, Typecode.DICTIONARY):
247
+ unicode_str_len = DataProperty(MultiByteStrDecoder(str(self.data)).unicode_str).length
248
+ assert unicode_str_len
249
+ return max(
250
+ ascii_char_width - (self.ascii_char_width - unicode_str_len),
251
+ 0,
252
+ )
253
+
254
+ try:
255
+ return max(ascii_char_width - (self.ascii_char_width - cast(int, self.length)), 0)
256
+ except TypeError:
257
+ return ascii_char_width
258
+
259
+ def to_str(self) -> str:
260
+ return self.format_str.format(self.data)
261
+
262
+ def __get_additional_format_len(self) -> int:
263
+ if not RealNumber(self.data, strip_ansi_escape=False).is_type():
264
+ return 0
265
+
266
+ format_len = 0
267
+
268
+ if Decimal(self.data) < 0:
269
+ # for minus character
270
+ format_len += 1
271
+
272
+ return format_len
273
+
274
+ def __get_base_float_len(self) -> int:
275
+ assert self.integer_digits is not None
276
+ assert self.decimal_places is not None
277
+
278
+ if any([self.integer_digits < 0, self.decimal_places < 0]):
279
+ raise ValueError("integer digits and decimal places must be greater or equals to zero")
280
+
281
+ float_len = self.integer_digits + self.decimal_places
282
+ if self.decimal_places > 0:
283
+ # for dot
284
+ float_len += 1
285
+
286
+ return float_len
287
+
288
+ def __get_length(self) -> Optional[int]:
289
+ if self.typecode in (Typecode.DICTIONARY, Typecode.LIST, Typecode.STRING):
290
+ return len(self.data)
291
+
292
+ return None
293
+
294
+ def __calc_ascii_char_width(self) -> int:
295
+ if self.typecode == Typecode.INTEGER:
296
+ return cast(int, self.integer_digits) + self.additional_format_len
297
+
298
+ if self.typecode == Typecode.REAL_NUMBER:
299
+ return self.__get_base_float_len() + self.additional_format_len
300
+
301
+ if self.typecode == Typecode.DATETIME:
302
+ try:
303
+ return len(self.to_str())
304
+ except ValueError:
305
+ # reach to this line if the year <1900.
306
+ # the datetime strftime() methods require year >= 1900.
307
+ return len(str(self.data))
308
+
309
+ if self.is_include_ansi_escape:
310
+ assert self.no_ansi_escape_dp
311
+ return self.no_ansi_escape_dp.ascii_char_width
312
+
313
+ try:
314
+ unicode_str = MultiByteStrDecoder(self.data).unicode_str
315
+ except ValueError:
316
+ unicode_str = self.to_str()
317
+
318
+ return calc_ascii_char_width(unicode_str, self._east_asian_ambiguous_width)
319
+
320
+ def __set_data(
321
+ self,
322
+ data: Any,
323
+ type_hint: TypeHint,
324
+ float_type: Optional[FloatType],
325
+ strict_level_map: Optional[StrictLevelMap],
326
+ ) -> None:
327
+ if float_type is None:
328
+ float_type = DefaultValue.FLOAT_TYPE
329
+
330
+ if strict_level_map is None:
331
+ strict_level_map = DefaultValue.STRICT_LEVEL_MAP
332
+
333
+ if type_hint:
334
+ type_obj = type_hint(
335
+ data, strict_level=StrictLevel.MIN, float_type=float_type, strip_ansi_escape=False
336
+ )
337
+ self._typecode = type_obj.typecode
338
+ self.__data = type_obj.try_convert()
339
+
340
+ if type_hint(
341
+ self.__data,
342
+ strict_level=StrictLevel.MAX,
343
+ float_type=float_type,
344
+ strip_ansi_escape=False,
345
+ ).is_type():
346
+ return
347
+
348
+ for type_class in self.__type_class_list:
349
+ strict_level = strict_level_map.get(
350
+ type_class(None, 0).typecode, strict_level_map.get("default", StrictLevel.MAX)
351
+ )
352
+
353
+ if self.__try_convert_type(data, type_class, strict_level, float_type):
354
+ return
355
+
356
+ raise TypeConversionError(
357
+ f"failed to convert: data={data}, strict_level={strict_level_map}"
358
+ )
359
+
360
+ def __set_digit(self) -> None:
361
+ integer_digits, decimal_places = get_number_of_digit(self.__data)
362
+ self.__integer_digits = integer_digits
363
+ self._decimal_places = decimal_places
364
+
365
+ def __try_convert_type(
366
+ self,
367
+ data: Any,
368
+ type_class: type[AbstractType],
369
+ strict_level: int,
370
+ float_type: Optional[FloatType],
371
+ ) -> bool:
372
+ type_obj = type_class(data, strict_level, float_type=float_type, strip_ansi_escape=False)
373
+
374
+ try:
375
+ self.__data = type_obj.convert()
376
+ except TypeConversionError:
377
+ return False
378
+
379
+ self._typecode = type_obj.typecode
380
+
381
+ return True
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_extractor.py ADDED
@@ -0,0 +1,817 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ import copy
6
+ import enum
7
+ import sys
8
+ import typing
9
+ from collections import Counter
10
+ from collections.abc import Sequence
11
+ from decimal import Decimal
12
+ from typing import Any, Optional, Union, cast
13
+
14
+ import typepy
15
+ from typepy import (
16
+ Bool,
17
+ DateTime,
18
+ Dictionary,
19
+ Infinity,
20
+ Integer,
21
+ IpAddress,
22
+ Nan,
23
+ NoneType,
24
+ NullString,
25
+ RealNumber,
26
+ StrictLevel,
27
+ String,
28
+ Typecode,
29
+ is_empty_sequence,
30
+ )
31
+ from typepy.type import AbstractType
32
+
33
+ from ._column import ColumnDataProperty
34
+ from ._common import MIN_STRICT_LEVEL_MAP, DefaultValue
35
+ from ._converter import DataPropertyConverter
36
+ from ._dataproperty import DataProperty
37
+ from ._formatter import Format
38
+ from ._preprocessor import Preprocessor
39
+ from .logger import logger # type: ignore
40
+ from .typing import (
41
+ DateTimeFormatter,
42
+ StrictLevelMap,
43
+ TransFunc,
44
+ TypeHint,
45
+ TypeValueMap,
46
+ normalize_type_hint,
47
+ )
48
+
49
+
50
+ DataPropertyMatrix = list[list[DataProperty]]
51
+
52
+
53
+ @enum.unique
54
+ class MatrixFormatting(enum.Enum):
55
+ # raise exception if the matrix is not properly formatted
56
+ EXCEPTION = 1 << 1
57
+
58
+ # trim to the minimum size column
59
+ TRIM = 1 << 2
60
+
61
+ # Append None values to columns so that it is the same as the maximum
62
+ # column size.
63
+ FILL_NONE = 1 << 3
64
+
65
+ HEADER_ALIGNED = 1 << 4
66
+
67
+
68
+ class DataPropertyExtractor:
69
+ """
70
+ .. py:attribute:: quoting_flags
71
+
72
+ Configurations to add double quote to for each items in a matrix,
73
+ where |Typecode| of table-value is |True| in the ``quote_flag_table``
74
+ mapping table. ``quote_flag_table`` should be a dictionary.
75
+ And is ``{ Typecode : bool }``. Defaults to:
76
+
77
+ .. code-block:: json
78
+ :caption: The default values
79
+
80
+ {
81
+ Typecode.BOOL: False,
82
+ Typecode.DATETIME: False,
83
+ Typecode.DICTIONARY: False,
84
+ Typecode.INFINITY: False,
85
+ Typecode.INTEGER: False,
86
+ Typecode.IP_ADDRESS: False,
87
+ Typecode.LIST: False,
88
+ Typecode.NAN: False,
89
+ Typecode.NULL_STRING: False,
90
+ Typecode.NONE: False,
91
+ Typecode.REAL_NUMBER: False,
92
+ Typecode.STRING: False,
93
+ }
94
+ """
95
+
96
+ def __init__(self, max_precision: Optional[int] = None) -> None:
97
+ self.max_workers = DefaultValue.MAX_WORKERS
98
+
99
+ if max_precision is None:
100
+ self.__max_precision = DefaultValue.MAX_PRECISION
101
+ else:
102
+ self.__max_precision = max_precision
103
+
104
+ self.__headers: Sequence[str] = []
105
+ self.__default_type_hint: TypeHint = None
106
+ self.__col_type_hints: list[TypeHint] = []
107
+
108
+ self.__strip_str_header: Optional[str] = None
109
+ self.__is_formatting_float = True
110
+ self.__min_col_ascii_char_width = 0
111
+ self.__default_format_flags = Format.NONE
112
+ self.__format_flags_list: Sequence[int] = []
113
+ self.__float_type: Union[type[float], type[Decimal], None] = None
114
+ self.__datetime_format_str = DefaultValue.DATETIME_FORMAT
115
+ self.__strict_level_map = copy.deepcopy(
116
+ cast(dict[Union[Typecode, str], int], DefaultValue.STRICT_LEVEL_MAP)
117
+ )
118
+ self.__east_asian_ambiguous_width = 1
119
+
120
+ self.__preprocessor = Preprocessor()
121
+
122
+ self.__type_value_map: TypeValueMap = copy.deepcopy(DefaultValue.TYPE_VALUE_MAP)
123
+
124
+ self.__trans_func_list: list[TransFunc] = []
125
+ self.__quoting_flags = copy.deepcopy(DefaultValue.QUOTING_FLAGS)
126
+ self.__datetime_formatter: Optional[DateTimeFormatter] = None
127
+ self.__matrix_formatting = MatrixFormatting.TRIM
128
+ self.__dp_converter: DataPropertyConverter
129
+
130
+ self.__clear_cache()
131
+
132
+ def __clear_cache(self) -> None:
133
+ self.__update_dp_converter()
134
+ self.__dp_cache_zero = self.__to_dp_raw(0)
135
+ self.__dp_cache_one = self.__to_dp_raw(1)
136
+ self.__dp_cache_true = self.__to_dp_raw(True)
137
+ self.__dp_cache_false = self.__to_dp_raw(False)
138
+ self.__dp_cache_map = {None: self.__to_dp_raw(None), "": self.__to_dp_raw("")}
139
+
140
+ @property
141
+ def headers(self) -> Sequence[str]:
142
+ return self.__headers
143
+
144
+ @headers.setter
145
+ def headers(self, value: Sequence[str]) -> None:
146
+ if self.__headers == value:
147
+ return
148
+
149
+ self.__headers = value
150
+ self.__clear_cache()
151
+
152
+ @property
153
+ def default_type_hint(self) -> TypeHint:
154
+ return self.__default_type_hint
155
+
156
+ @default_type_hint.setter
157
+ def default_type_hint(self, value: TypeHint) -> None:
158
+ if self.__default_type_hint == value:
159
+ return
160
+
161
+ self.__default_type_hint = value
162
+ self.__clear_cache()
163
+
164
+ @property
165
+ def column_type_hints(self) -> list[TypeHint]:
166
+ return self.__col_type_hints
167
+
168
+ @column_type_hints.setter
169
+ def column_type_hints(self, value: Sequence[Union[str, TypeHint]]) -> None:
170
+ normalized_type_hints: list[TypeHint] = []
171
+
172
+ for type_hint in value:
173
+ type_hint = normalize_type_hint(type_hint)
174
+ if type_hint not in (
175
+ Bool,
176
+ DateTime,
177
+ Dictionary,
178
+ Infinity,
179
+ Integer,
180
+ IpAddress,
181
+ typepy.List,
182
+ Nan,
183
+ NoneType,
184
+ RealNumber,
185
+ String,
186
+ NullString,
187
+ None,
188
+ ):
189
+ raise ValueError(f"invalid type hint: {type(type_hint)}")
190
+
191
+ normalized_type_hints.append(type_hint)
192
+
193
+ if self.__col_type_hints == normalized_type_hints:
194
+ return
195
+
196
+ self.__col_type_hints = normalized_type_hints
197
+ self.__clear_cache()
198
+
199
+ @property
200
+ def is_formatting_float(self) -> bool:
201
+ return self.__is_formatting_float
202
+
203
+ @is_formatting_float.setter
204
+ def is_formatting_float(self, value: bool) -> None:
205
+ self.__is_formatting_float = value
206
+
207
+ @property
208
+ def max_precision(self) -> int:
209
+ return self.__max_precision
210
+
211
+ @max_precision.setter
212
+ def max_precision(self, value: int) -> None:
213
+ if self.__max_precision == value:
214
+ return
215
+
216
+ self.__max_precision = value
217
+ self.__clear_cache()
218
+
219
+ @property
220
+ def preprocessor(self) -> Preprocessor:
221
+ return self.__preprocessor
222
+
223
+ @preprocessor.setter
224
+ def preprocessor(self, value: Preprocessor) -> None:
225
+ if self.preprocessor == value:
226
+ return
227
+
228
+ self.__preprocessor = value
229
+ self.__update_dp_converter()
230
+
231
+ @property
232
+ def strip_str_header(self) -> Optional[str]:
233
+ return self.__strip_str_header
234
+
235
+ @strip_str_header.setter
236
+ def strip_str_header(self, value: str) -> None:
237
+ if self.__strip_str_header == value:
238
+ return
239
+
240
+ self.__strip_str_header = value
241
+ self.__clear_cache()
242
+
243
+ @property
244
+ def min_column_width(self) -> int:
245
+ return self.__min_col_ascii_char_width
246
+
247
+ @min_column_width.setter
248
+ def min_column_width(self, value: int) -> None:
249
+ if self.__min_col_ascii_char_width == value:
250
+ return
251
+
252
+ self.__min_col_ascii_char_width = value
253
+ self.__clear_cache()
254
+
255
+ @property
256
+ def default_format_flags(self) -> int:
257
+ return self.__default_format_flags
258
+
259
+ @default_format_flags.setter
260
+ def default_format_flags(self, value: int) -> None:
261
+ if self.__default_format_flags == value:
262
+ return
263
+
264
+ self.__default_format_flags = value
265
+ self.__clear_cache()
266
+
267
+ @property
268
+ def format_flags_list(self) -> Sequence[int]:
269
+ return self.__format_flags_list
270
+
271
+ @format_flags_list.setter
272
+ def format_flags_list(self, value: Sequence[int]) -> None:
273
+ if self.__format_flags_list == value:
274
+ return
275
+
276
+ self.__format_flags_list = value
277
+ self.__clear_cache()
278
+
279
+ @property
280
+ def float_type(self) -> Union[type[float], type[Decimal], None]:
281
+ return self.__float_type
282
+
283
+ @float_type.setter
284
+ def float_type(self, value: Union[type[float], type[Decimal]]) -> None:
285
+ if self.__float_type == value:
286
+ return
287
+
288
+ self.__float_type = value
289
+ self.__clear_cache()
290
+
291
+ @property
292
+ def datetime_format_str(self) -> str:
293
+ return self.__datetime_format_str
294
+
295
+ @datetime_format_str.setter
296
+ def datetime_format_str(self, value: str) -> None:
297
+ if self.__datetime_format_str == value:
298
+ return
299
+
300
+ self.__datetime_format_str = value
301
+ self.__clear_cache()
302
+
303
+ @property
304
+ def strict_level_map(self) -> StrictLevelMap:
305
+ return self.__strict_level_map
306
+
307
+ @strict_level_map.setter
308
+ def strict_level_map(self, value: StrictLevelMap) -> None:
309
+ if self.__strict_level_map == value:
310
+ return
311
+
312
+ self.__strict_level_map = cast(dict[Union[Typecode, str], int], value)
313
+ self.__clear_cache()
314
+
315
+ @property
316
+ def east_asian_ambiguous_width(self) -> int:
317
+ return self.__east_asian_ambiguous_width
318
+
319
+ @east_asian_ambiguous_width.setter
320
+ def east_asian_ambiguous_width(self, value: int) -> None:
321
+ if self.__east_asian_ambiguous_width == value:
322
+ return
323
+
324
+ self.__east_asian_ambiguous_width = value
325
+ self.__clear_cache()
326
+
327
+ @property
328
+ def type_value_map(self) -> TypeValueMap:
329
+ return self.__type_value_map
330
+
331
+ @type_value_map.setter
332
+ def type_value_map(self, value: TypeValueMap) -> None:
333
+ if self.__type_value_map == value:
334
+ return
335
+
336
+ self.__type_value_map = value
337
+ self.__clear_cache()
338
+
339
+ def set_type_value(self, key: Typecode, value: Union[float, str, Decimal, None]) -> None:
340
+ self.__type_value_map[key] = value
341
+ self.__clear_cache()
342
+
343
+ def register_trans_func(self, trans_func: TransFunc) -> None:
344
+ self.__trans_func_list.insert(0, trans_func)
345
+ self.__clear_cache()
346
+
347
+ @property
348
+ def quoting_flags(self) -> dict[Typecode, bool]:
349
+ return self.__quoting_flags
350
+
351
+ @quoting_flags.setter
352
+ def quoting_flags(self, value: dict[Typecode, bool]) -> None:
353
+ if self.__quoting_flags == value:
354
+ return
355
+
356
+ self.__quoting_flags = value
357
+ self.__clear_cache()
358
+
359
+ @property
360
+ def datetime_formatter(self) -> Optional[DateTimeFormatter]:
361
+ return self.__datetime_formatter
362
+
363
+ @datetime_formatter.setter
364
+ def datetime_formatter(self, value: Optional[DateTimeFormatter]) -> None:
365
+ if self.__datetime_formatter == value:
366
+ return
367
+
368
+ self.__datetime_formatter = value
369
+ self.__clear_cache()
370
+
371
+ @property
372
+ def matrix_formatting(self) -> MatrixFormatting:
373
+ return self.__matrix_formatting
374
+
375
+ @matrix_formatting.setter
376
+ def matrix_formatting(self, value: MatrixFormatting) -> None:
377
+ if self.__matrix_formatting == value:
378
+ return
379
+
380
+ self.__matrix_formatting = value
381
+ self.__clear_cache()
382
+
383
+ @property
384
+ def max_workers(self) -> int:
385
+ assert self.__max_workers
386
+
387
+ return self.__max_workers
388
+
389
+ @max_workers.setter
390
+ def max_workers(self, value: Optional[int]) -> None:
391
+ try:
392
+ from _multiprocessing import SemLock, sem_unlink # noqa
393
+ except ImportError:
394
+ logger.debug("This platform lacks a functioning sem_open implementation")
395
+ value = 1
396
+
397
+ if "pytest" in sys.modules and value != 1:
398
+ logger.debug("set max_workers to 1 to avoid deadlock when executed from pytest")
399
+ value = 1
400
+
401
+ self.__max_workers = value
402
+ if not self.__max_workers:
403
+ self.__max_workers = DefaultValue.MAX_WORKERS
404
+
405
+ def to_dp(self, value: Any) -> DataProperty:
406
+ self.__update_dp_converter()
407
+
408
+ return self.__to_dp(value)
409
+
410
+ def to_dp_list(self, values: Sequence[Any]) -> list[DataProperty]:
411
+ if is_empty_sequence(values):
412
+ return []
413
+
414
+ self.__update_dp_converter()
415
+
416
+ return self._to_dp_list(values)
417
+
418
+ def to_column_dp_list(
419
+ self,
420
+ value_dp_matrix: Any,
421
+ previous_column_dp_list: Optional[Sequence[ColumnDataProperty]] = None,
422
+ ) -> list[ColumnDataProperty]:
423
+ col_dp_list = self.__get_col_dp_list_base()
424
+
425
+ logger.debug("converting to column dataproperty:")
426
+
427
+ logs = [" params:"]
428
+ if self.headers:
429
+ logs.append(f" headers={len(self.headers)}")
430
+ logs.extend(
431
+ [
432
+ " prev_col_count={}".format(
433
+ len(previous_column_dp_list) if previous_column_dp_list else None
434
+ ),
435
+ f" matrix_formatting={self.matrix_formatting}",
436
+ ]
437
+ )
438
+ if self.column_type_hints:
439
+ logs.append(
440
+ " column_type_hints=({})".format(
441
+ ", ".join(
442
+ [
443
+ type_hint.__name__ if type_hint else "none"
444
+ for type_hint in self.column_type_hints
445
+ ]
446
+ )
447
+ )
448
+ )
449
+ else:
450
+ logs.append(" column_type_hints=()")
451
+
452
+ for log in logs:
453
+ logger.debug(log)
454
+
455
+ logger.debug(" results:")
456
+ for col_idx, value_dp_list in enumerate(zip(*value_dp_matrix)):
457
+ try:
458
+ col_dp_list[col_idx]
459
+ except IndexError:
460
+ col_dp_list.append(
461
+ ColumnDataProperty(
462
+ column_index=col_idx,
463
+ float_type=self.float_type,
464
+ min_width=self.min_column_width,
465
+ format_flags=self.__get_format_flags(col_idx),
466
+ is_formatting_float=self.is_formatting_float,
467
+ datetime_format_str=self.datetime_format_str,
468
+ east_asian_ambiguous_width=self.east_asian_ambiguous_width,
469
+ max_precision=self.__max_precision,
470
+ )
471
+ )
472
+
473
+ col_dp = col_dp_list[col_idx]
474
+ col_dp.begin_update()
475
+
476
+ try:
477
+ col_dp.merge(previous_column_dp_list[col_idx]) # type: ignore
478
+ except (TypeError, IndexError):
479
+ pass
480
+
481
+ for value_dp in value_dp_list:
482
+ col_dp.update_body(value_dp)
483
+
484
+ col_dp.end_update()
485
+
486
+ logger.debug(f" {str(col_dp):s}")
487
+
488
+ return col_dp_list
489
+
490
+ def to_dp_matrix(self, value_matrix: Sequence[Sequence[Any]]) -> DataPropertyMatrix:
491
+ self.__update_dp_converter()
492
+ logger.debug(f"max_workers={self.max_workers}, preprocessor={self.__preprocessor}")
493
+
494
+ value_matrix = self.__strip_data_matrix(value_matrix)
495
+
496
+ if self.__is_dp_matrix(value_matrix):
497
+ logger.debug("already a dataproperty matrix")
498
+ return value_matrix # type: ignore
499
+
500
+ if self.max_workers <= 1:
501
+ return self.__to_dp_matrix_st(value_matrix)
502
+
503
+ return self.__to_dp_matrix_mt(value_matrix)
504
+
505
+ def to_header_dp_list(self) -> list[DataProperty]:
506
+ self.__update_dp_converter()
507
+
508
+ preprocessor = copy.deepcopy(self.__preprocessor)
509
+ preprocessor.strip_str = self.strip_str_header
510
+
511
+ return self._to_dp_list(
512
+ self.headers,
513
+ type_hint=String,
514
+ preprocessor=preprocessor,
515
+ strict_level_map=MIN_STRICT_LEVEL_MAP,
516
+ )
517
+
518
+ def update_preprocessor(self, **kwargs: Any) -> bool:
519
+ is_updated = self.__preprocessor.update(**kwargs)
520
+ self.__update_dp_converter()
521
+
522
+ return is_updated
523
+
524
+ def update_strict_level_map(self, value: StrictLevelMap) -> bool:
525
+ org = copy.deepcopy(self.__strict_level_map)
526
+ self.__strict_level_map.update(value)
527
+
528
+ if org == self.__strict_level_map:
529
+ return False
530
+
531
+ self.__clear_cache()
532
+
533
+ return True
534
+
535
+ """
536
+ def update_dict(self, lhs: Mapping, rhs: Mapping) -> bool:
537
+ is_updated = False
538
+
539
+ for key, value in rhs.items():
540
+ if key not in lhs:
541
+ lhs[]
542
+ continue
543
+
544
+ if getattr(lhs, key) == value:
545
+ continue
546
+
547
+ setattr(lhs, key, value)
548
+ is_updated = True
549
+
550
+ return is_updated
551
+ """
552
+
553
+ @staticmethod
554
+ def __is_dp_matrix(value: Any) -> bool:
555
+ try:
556
+ return isinstance(value[0][0], DataProperty)
557
+ except (TypeError, IndexError):
558
+ return False
559
+
560
+ def __get_col_type_hint(self, col_idx: int) -> TypeHint:
561
+ try:
562
+ return self.column_type_hints[col_idx]
563
+ except (TypeError, IndexError):
564
+ return self.default_type_hint
565
+
566
+ def __get_format_flags(self, col_idx: int) -> int:
567
+ try:
568
+ return self.format_flags_list[col_idx]
569
+ except (TypeError, IndexError):
570
+ return self.__default_format_flags
571
+
572
+ def __to_dp(
573
+ self,
574
+ data: Any,
575
+ type_hint: TypeHint = None,
576
+ preprocessor: Optional[Preprocessor] = None,
577
+ strict_level_map: Optional[StrictLevelMap] = None,
578
+ ) -> DataProperty:
579
+ for trans_func in self.__trans_func_list:
580
+ data = trans_func(data)
581
+
582
+ if type_hint:
583
+ return self.__to_dp_raw(
584
+ data,
585
+ type_hint=type_hint,
586
+ preprocessor=preprocessor,
587
+ strict_level_map=strict_level_map,
588
+ )
589
+
590
+ try:
591
+ if data in self.__dp_cache_map:
592
+ return self.__dp_cache_map[data]
593
+ except TypeError:
594
+ # unhashable type
595
+ pass
596
+
597
+ if data == 0:
598
+ if data is False:
599
+ return self.__dp_cache_false
600
+ return self.__dp_cache_zero
601
+ if data == 1:
602
+ if data is True:
603
+ return self.__dp_cache_true
604
+ return self.__dp_cache_one
605
+
606
+ return self.__to_dp_raw(
607
+ data, type_hint=type_hint, preprocessor=preprocessor, strict_level_map=strict_level_map
608
+ )
609
+
610
+ def __to_dp_raw(
611
+ self,
612
+ data: Any,
613
+ type_hint: TypeHint = None,
614
+ preprocessor: Optional[Preprocessor] = None,
615
+ strict_level_map: Optional[StrictLevelMap] = None,
616
+ ) -> DataProperty:
617
+ if preprocessor:
618
+ preprocessor = Preprocessor(
619
+ dequote=preprocessor.dequote,
620
+ line_break_handling=preprocessor.line_break_handling,
621
+ line_break_repl=preprocessor.line_break_repl,
622
+ strip_str=preprocessor.strip_str,
623
+ is_escape_formula_injection=preprocessor.is_escape_formula_injection,
624
+ )
625
+ else:
626
+ preprocessor = Preprocessor(
627
+ dequote=self.preprocessor.dequote,
628
+ line_break_handling=self.preprocessor.line_break_handling,
629
+ line_break_repl=self.preprocessor.line_break_repl,
630
+ strip_str=self.preprocessor.strip_str,
631
+ is_escape_formula_injection=self.__preprocessor.is_escape_formula_injection,
632
+ )
633
+
634
+ value_dp = DataProperty(
635
+ data,
636
+ preprocessor=preprocessor,
637
+ type_hint=(type_hint if type_hint is not None else self.default_type_hint),
638
+ float_type=self.float_type,
639
+ datetime_format_str=self.datetime_format_str,
640
+ strict_level_map=(strict_level_map if type_hint is not None else self.strict_level_map),
641
+ east_asian_ambiguous_width=self.east_asian_ambiguous_width,
642
+ )
643
+
644
+ return self.__dp_converter.convert(value_dp)
645
+
646
+ def __to_dp_matrix_st(self, value_matrix: Sequence[Sequence[Any]]) -> DataPropertyMatrix:
647
+ return list(
648
+ zip( # type: ignore
649
+ *(
650
+ _to_dp_list_helper(
651
+ self,
652
+ col_idx,
653
+ values,
654
+ self.__get_col_type_hint(col_idx),
655
+ self.__preprocessor,
656
+ )[1]
657
+ for col_idx, values in enumerate(zip(*value_matrix))
658
+ )
659
+ )
660
+ )
661
+
662
+ def __to_dp_matrix_mt(self, value_matrix: Sequence[Sequence[Any]]) -> DataPropertyMatrix:
663
+ from concurrent import futures
664
+
665
+ col_data_map = {}
666
+
667
+ with futures.ProcessPoolExecutor(self.max_workers) as executor:
668
+ future_list = [
669
+ executor.submit(
670
+ _to_dp_list_helper,
671
+ self,
672
+ col_idx,
673
+ values,
674
+ self.__get_col_type_hint(col_idx),
675
+ self.__preprocessor,
676
+ )
677
+ for col_idx, values in enumerate(zip(*value_matrix))
678
+ ]
679
+
680
+ for future in futures.as_completed(future_list):
681
+ col_idx, value_dp_list = future.result()
682
+ col_data_map[col_idx] = value_dp_list
683
+
684
+ return list(
685
+ zip(*(col_data_map[col_idx] for col_idx in sorted(col_data_map))) # type: ignore
686
+ )
687
+
688
+ def _to_dp_list(
689
+ self,
690
+ data_list: Sequence[Any],
691
+ type_hint: TypeHint = None,
692
+ preprocessor: Optional[Preprocessor] = None,
693
+ strict_level_map: Optional[StrictLevelMap] = None,
694
+ ) -> list[DataProperty]:
695
+ if is_empty_sequence(data_list):
696
+ return []
697
+
698
+ type_counter: typing.Counter[type[AbstractType]] = Counter()
699
+
700
+ dp_list = []
701
+ for data in data_list:
702
+ expect_type_hint: TypeHint = type_hint
703
+ if type_hint is None:
704
+ try:
705
+ expect_type_hint, _count = type_counter.most_common(1)[0]
706
+ if not expect_type_hint(
707
+ data, float_type=self.float_type, strict_level=StrictLevel.MAX
708
+ ).is_type():
709
+ expect_type_hint = None
710
+ except IndexError:
711
+ pass
712
+
713
+ dataprop = self.__to_dp(
714
+ data=data,
715
+ type_hint=expect_type_hint,
716
+ preprocessor=preprocessor if preprocessor else self.__preprocessor,
717
+ strict_level_map=strict_level_map,
718
+ )
719
+ type_counter[dataprop.type_class] += 1
720
+
721
+ dp_list.append(dataprop)
722
+
723
+ return dp_list
724
+
725
+ def __strip_data_matrix(self, data_matrix: Sequence[Sequence[Any]]) -> Sequence[Sequence[Any]]:
726
+ header_col_size = len(self.headers) if self.headers else 0
727
+ try:
728
+ col_size_list = [len(data_list) for data_list in data_matrix]
729
+ except TypeError:
730
+ return []
731
+
732
+ if self.headers:
733
+ min_col_size = min([header_col_size] + col_size_list)
734
+ max_col_size = max([header_col_size] + col_size_list)
735
+ elif col_size_list:
736
+ min_col_size = min(col_size_list)
737
+ max_col_size = max(col_size_list)
738
+ else:
739
+ min_col_size = 0
740
+ max_col_size = 0
741
+
742
+ if self.matrix_formatting == MatrixFormatting.EXCEPTION:
743
+ if min_col_size != max_col_size:
744
+ raise ValueError(
745
+ "nonuniform column size found: min={}, max={}".format(
746
+ min_col_size, max_col_size
747
+ )
748
+ )
749
+
750
+ return data_matrix
751
+
752
+ if self.matrix_formatting == MatrixFormatting.HEADER_ALIGNED:
753
+ if header_col_size > 0:
754
+ format_col_size = header_col_size
755
+ else:
756
+ format_col_size = max_col_size
757
+ elif self.matrix_formatting == MatrixFormatting.TRIM:
758
+ format_col_size = min_col_size
759
+ elif self.matrix_formatting == MatrixFormatting.FILL_NONE:
760
+ format_col_size = max_col_size
761
+ else:
762
+ raise ValueError(f"unknown matrix formatting: {self.matrix_formatting}")
763
+
764
+ return [
765
+ list(data_matrix[row_idx][:format_col_size]) + [None] * (format_col_size - col_size)
766
+ for row_idx, col_size in enumerate(col_size_list)
767
+ ]
768
+
769
+ def __get_col_dp_list_base(self) -> list[ColumnDataProperty]:
770
+ header_dp_list = self.to_header_dp_list()
771
+ col_dp_list = []
772
+
773
+ for col_idx, header_dp in enumerate(header_dp_list):
774
+ col_dp = ColumnDataProperty(
775
+ column_index=col_idx,
776
+ float_type=self.float_type,
777
+ min_width=self.min_column_width,
778
+ format_flags=self.__get_format_flags(col_idx),
779
+ is_formatting_float=self.is_formatting_float,
780
+ datetime_format_str=self.datetime_format_str,
781
+ east_asian_ambiguous_width=self.east_asian_ambiguous_width,
782
+ max_precision=self.__max_precision,
783
+ )
784
+ col_dp.update_header(header_dp)
785
+ col_dp_list.append(col_dp)
786
+
787
+ return col_dp_list
788
+
789
+ def __update_dp_converter(self) -> None:
790
+ preprocessor = Preprocessor(
791
+ line_break_handling=self.__preprocessor.line_break_handling,
792
+ line_break_repl=self.preprocessor.line_break_repl,
793
+ is_escape_html_tag=self.__preprocessor.is_escape_html_tag,
794
+ is_escape_formula_injection=self.__preprocessor.is_escape_formula_injection,
795
+ )
796
+ self.__dp_converter = DataPropertyConverter(
797
+ preprocessor=preprocessor,
798
+ type_value_map=self.type_value_map,
799
+ quoting_flags=self.quoting_flags,
800
+ datetime_formatter=self.datetime_formatter,
801
+ datetime_format_str=self.datetime_format_str,
802
+ float_type=self.float_type,
803
+ strict_level_map=self.strict_level_map,
804
+ )
805
+
806
+
807
+ def _to_dp_list_helper(
808
+ extractor: DataPropertyExtractor,
809
+ col_idx: int,
810
+ data_list: Sequence[Any],
811
+ type_hint: TypeHint,
812
+ preprocessor: Preprocessor,
813
+ ) -> tuple[int, list[DataProperty]]:
814
+ return (
815
+ col_idx,
816
+ extractor._to_dp_list(data_list, type_hint=type_hint, preprocessor=preprocessor),
817
+ )
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_formatter.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import copy
2
+ from decimal import Decimal
3
+ from typing import Final, Optional, Union
4
+
5
+ from typepy import Nan, Typecode
6
+
7
+
8
+ DecimalPlaces = Union[float, Decimal]
9
+
10
+
11
+ class Format:
12
+ NONE: Final = 0
13
+ THOUSAND_SEPARATOR: Final = 1
14
+
15
+
16
+ class Formatter:
17
+ __slots__ = ("__is_formatting_float", "__format_flags", "__datetime_format_str")
18
+
19
+ _BLANK_CURLY_BRACES_FORMAT_MAP: Final[dict[Typecode, str]] = {
20
+ Typecode.NONE: "{}",
21
+ Typecode.IP_ADDRESS: "{}",
22
+ Typecode.BOOL: "{}",
23
+ Typecode.DICTIONARY: "{}",
24
+ Typecode.LIST: "{}",
25
+ }
26
+
27
+ def __init__(
28
+ self,
29
+ datetime_format_str: str,
30
+ is_formatting_float: Optional[bool] = True,
31
+ format_flags: Optional[int] = None,
32
+ ) -> None:
33
+ if format_flags is not None:
34
+ self.__format_flags = format_flags
35
+ else:
36
+ self.__format_flags = Format.NONE
37
+
38
+ self.__datetime_format_str = datetime_format_str
39
+ self.__is_formatting_float = is_formatting_float
40
+
41
+ def make_format_map(
42
+ self, decimal_places: Optional[DecimalPlaces] = None
43
+ ) -> dict[Typecode, str]:
44
+ format_map = copy.copy(self._BLANK_CURLY_BRACES_FORMAT_MAP)
45
+ format_map.update(
46
+ {
47
+ Typecode.INTEGER: self.make_format_str(Typecode.INTEGER),
48
+ Typecode.REAL_NUMBER: self.make_format_str(Typecode.REAL_NUMBER, decimal_places),
49
+ Typecode.INFINITY: self.make_format_str(Typecode.INFINITY),
50
+ Typecode.NAN: self.make_format_str(Typecode.NAN),
51
+ Typecode.DATETIME: self.make_format_str(Typecode.DATETIME),
52
+ }
53
+ )
54
+
55
+ return format_map
56
+
57
+ def make_format_str(
58
+ self, typecode: Typecode, decimal_places: Optional[DecimalPlaces] = None
59
+ ) -> str:
60
+ format_str = self._BLANK_CURLY_BRACES_FORMAT_MAP.get(typecode)
61
+ if format_str is not None:
62
+ return format_str
63
+
64
+ if typecode == Typecode.INTEGER:
65
+ return self.__get_integer_format()
66
+
67
+ if typecode in (Typecode.REAL_NUMBER, Typecode.INFINITY, Typecode.NAN):
68
+ return self.__get_realnumber_format(decimal_places)
69
+
70
+ if typecode == Typecode.DATETIME:
71
+ return "{:" + self.__datetime_format_str + "}"
72
+
73
+ return "{:s}"
74
+
75
+ def __get_base_format_str(self) -> str:
76
+ if self.__format_flags & Format.THOUSAND_SEPARATOR:
77
+ return ","
78
+
79
+ return ""
80
+
81
+ def __get_integer_format(self) -> str:
82
+ return "{:" + self.__get_base_format_str() + "d}"
83
+
84
+ def __get_realnumber_format(self, decimal_places: Optional[DecimalPlaces]) -> str:
85
+ if not self.__is_formatting_float:
86
+ return "{}"
87
+
88
+ base_format = self.__get_base_format_str()
89
+
90
+ if decimal_places is None or Nan(decimal_places).is_type():
91
+ return "{:" + base_format + "f}"
92
+
93
+ try:
94
+ return "{:" + f"{base_format:s}.{decimal_places:d}f" + "}"
95
+ except ValueError:
96
+ pass
97
+
98
+ return "{:" + base_format + "f}"
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_function.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ import decimal
6
+ import re
7
+ from decimal import Decimal
8
+ from typing import Any, Final, Optional, Union
9
+
10
+ from typepy import Integer, RealNumber, TypeConversionError
11
+
12
+
13
+ _ansi_escape: Final = re.compile(r"(\x9b|\x1b\[)[0-?]*[ -\/]*[@-~]", re.IGNORECASE)
14
+
15
+
16
+ def get_integer_digit(value: Any) -> int:
17
+ float_type: Final = RealNumber(value)
18
+
19
+ with decimal.localcontext() as ctx:
20
+ ctx.prec = 60
21
+ ctx.rounding = decimal.ROUND_HALF_DOWN
22
+
23
+ try:
24
+ abs_value = abs(float_type.convert())
25
+ except TypeConversionError:
26
+ try:
27
+ abs_value = abs(Integer(value).convert())
28
+ except TypeConversionError:
29
+ raise ValueError(
30
+ f"the value must be a number: value='{value}' type='{type(value)}'"
31
+ )
32
+
33
+ return len(str(abs_value))
34
+
35
+ if abs_value.is_zero():
36
+ return 1
37
+
38
+ try:
39
+ return len(str(abs_value.quantize(Decimal("1."), rounding=decimal.ROUND_DOWN)))
40
+ except decimal.InvalidOperation:
41
+ return len(str(abs_value))
42
+
43
+
44
+ class DigitCalculator:
45
+ REGEXP_COMMON_LOG: Final = re.compile(r"[\d\.]+[eE]\-\d+")
46
+ REGEXP_SPLIT: Final = re.compile(r"[eE]\-")
47
+
48
+ def get_decimal_places(self, value: Union[str, float, int, Decimal]) -> int:
49
+ if Integer(value).is_type():
50
+ return 0
51
+
52
+ float_digit_len = 0
53
+ abs_value = abs(float(value))
54
+ text_value = str(abs_value)
55
+ float_text = "0"
56
+ if text_value.find(".") != -1:
57
+ float_text = text_value.split(".")[1]
58
+ float_digit_len = len(float_text)
59
+ elif self.REGEXP_COMMON_LOG.search(text_value):
60
+ float_text = self.REGEXP_SPLIT.split(text_value)[1]
61
+ float_digit_len = int(float_text)
62
+
63
+ return float_digit_len
64
+
65
+
66
+ _digit_calculator = DigitCalculator()
67
+
68
+
69
+ def get_number_of_digit(
70
+ value: Any, max_decimal_places: int = 99
71
+ ) -> tuple[Optional[int], Optional[int]]:
72
+ try:
73
+ integer_digits = get_integer_digit(value)
74
+ except (ValueError, TypeError, OverflowError):
75
+ return (None, None)
76
+
77
+ try:
78
+ decimal_places: Optional[int] = min(
79
+ _digit_calculator.get_decimal_places(value), max_decimal_places
80
+ )
81
+ except (ValueError, TypeError):
82
+ decimal_places = None
83
+
84
+ return (integer_digits, decimal_places)
85
+
86
+
87
+ def _validate_eaaw(east_asian_ambiguous_width: int) -> None:
88
+ if east_asian_ambiguous_width in (1, 2):
89
+ return
90
+
91
+ raise ValueError(
92
+ "invalid east_asian_ambiguous_width: expected=1 or 2, actual={}".format(
93
+ east_asian_ambiguous_width
94
+ )
95
+ )
96
+
97
+
98
+ def strip_ansi_escape(unicode_str: str) -> str:
99
+ return _ansi_escape.sub("", unicode_str)
100
+
101
+
102
+ def calc_ascii_char_width(unicode_str: str, east_asian_ambiguous_width: int = 1) -> int:
103
+ import unicodedata
104
+
105
+ width = 0
106
+ for char in unicode_str:
107
+ char_width = unicodedata.east_asian_width(char)
108
+ if char_width in "WF":
109
+ width += 2
110
+ elif char_width == "A":
111
+ _validate_eaaw(east_asian_ambiguous_width)
112
+ width += east_asian_ambiguous_width
113
+ else:
114
+ width += 1
115
+
116
+ return width
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_interface.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com>
3
+ """
4
+
5
+ import abc
6
+ from typing import Optional
7
+
8
+ from typepy import Typecode
9
+
10
+ from ._align import Align
11
+
12
+
13
+ class DataPeropertyInterface(metaclass=abc.ABCMeta):
14
+ __slots__ = ()
15
+
16
+ @property
17
+ @abc.abstractmethod
18
+ def align(self) -> Align: # pragma: no cover
19
+ pass
20
+
21
+ @property
22
+ @abc.abstractmethod
23
+ def decimal_places(self) -> Optional[int]: # pragma: no cover
24
+ pass
25
+
26
+ @property
27
+ @abc.abstractmethod
28
+ def typecode(self) -> Typecode: # pragma: no cover
29
+ pass
30
+
31
+ @property
32
+ @abc.abstractmethod
33
+ def typename(self) -> str: # pragma: no cover
34
+ pass
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_line_break.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ from enum import Enum, unique
2
+
3
+
4
+ @unique
5
+ class LineBreakHandling(Enum):
6
+ NOP = 0
7
+ REPLACE = 1
8
+ ESCAPE = 2
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/_preprocessor.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import html
2
+ import re
3
+ from typing import Any, Final, Optional, Union
4
+
5
+ from mbstrdecoder import MultiByteStrDecoder
6
+
7
+ from ._function import strip_ansi_escape
8
+ from ._line_break import LineBreakHandling
9
+
10
+
11
+ _RE_LINE_BREAK: Final = re.compile(r"\r\n|\n")
12
+ _RE_FORMULA_PREFIX: Final = re.compile(r"^[-\+=@]")
13
+
14
+
15
+ def normalize_lbh(value: Optional[LineBreakHandling]) -> LineBreakHandling:
16
+ if isinstance(value, LineBreakHandling):
17
+ return value
18
+
19
+ if value is None:
20
+ return LineBreakHandling.NOP
21
+
22
+ return LineBreakHandling[value.upper()] # type: ignore
23
+
24
+
25
+ class Preprocessor:
26
+ @property
27
+ def line_break_handling(self) -> Optional[LineBreakHandling]:
28
+ return self.__line_break_handling
29
+
30
+ @line_break_handling.setter
31
+ def line_break_handling(self, value: Optional[LineBreakHandling]) -> None:
32
+ self.__line_break_handling = normalize_lbh(value)
33
+
34
+ def __init__(
35
+ self,
36
+ strip_str: Optional[Union[str, bytes]] = None,
37
+ replace_tabs_with_spaces: bool = True,
38
+ tab_length: int = 2,
39
+ line_break_handling: Optional[LineBreakHandling] = None,
40
+ line_break_repl: str = " ",
41
+ dequote: bool = False,
42
+ is_escape_html_tag: bool = False,
43
+ is_escape_formula_injection: bool = False,
44
+ ) -> None:
45
+ self.strip_str = strip_str
46
+ self.replace_tabs_with_spaces = replace_tabs_with_spaces
47
+ self.tab_length = tab_length
48
+ self.line_break_handling = line_break_handling
49
+ self.line_break_repl = line_break_repl
50
+ self.dequote = dequote
51
+ self.is_escape_html_tag = is_escape_html_tag
52
+ self.is_escape_formula_injection = is_escape_formula_injection
53
+
54
+ def __repr__(self) -> str:
55
+ return ", ".join(
56
+ [
57
+ f"strip_str={self.strip_str!r}",
58
+ f"replace_tabs_with_spaces={self.replace_tabs_with_spaces}",
59
+ f"tab_length={self.tab_length}",
60
+ f"line_break_handling={self.line_break_handling}",
61
+ f"line_break_repl={self.line_break_repl}",
62
+ f"escape_html_tag={self.is_escape_html_tag}",
63
+ f"escape_formula_injection={self.is_escape_formula_injection}",
64
+ ]
65
+ )
66
+
67
+ def preprocess(self, data: Any) -> tuple:
68
+ data, no_ansi_escape_data = self.__preprocess_string(
69
+ self.__preprocess_data(data, self.strip_str),
70
+ )
71
+ return (data, no_ansi_escape_data)
72
+
73
+ def update(self, **kwargs: Any) -> bool:
74
+ is_updated = False
75
+
76
+ for key, value in kwargs.items():
77
+ if not hasattr(self, key):
78
+ continue
79
+
80
+ if getattr(self, key) == value:
81
+ continue
82
+
83
+ setattr(self, key, value)
84
+ is_updated = True
85
+
86
+ return is_updated
87
+
88
+ def __preprocess_string(self, raw_data: Any) -> tuple[Any, Optional[str]]:
89
+ data = raw_data
90
+
91
+ if not isinstance(data, str):
92
+ return (data, None)
93
+
94
+ if self.replace_tabs_with_spaces:
95
+ try:
96
+ data = data.replace("\t", " " * self.tab_length)
97
+ except (TypeError, AttributeError, ValueError):
98
+ pass
99
+
100
+ if self.is_escape_html_tag:
101
+ try:
102
+ data = html.escape(data)
103
+ except AttributeError:
104
+ return (data, None)
105
+
106
+ data = self.__process_line_break(data)
107
+ data = self.__escape_formula_injection(data)
108
+ data = self.__dequote(data)
109
+
110
+ try:
111
+ return (data, strip_ansi_escape(data))
112
+ except TypeError:
113
+ return (data, None)
114
+
115
+ @staticmethod
116
+ def __preprocess_data(data: Any, strip_str: Optional[Union[str, bytes]]) -> Any:
117
+ if strip_str is None:
118
+ return data
119
+
120
+ try:
121
+ return data.strip(strip_str)
122
+ except AttributeError:
123
+ return data
124
+ except UnicodeDecodeError:
125
+ return MultiByteStrDecoder(data).unicode_str.strip(str(strip_str))
126
+ except TypeError:
127
+ # reach here when data and strip_str type are different
128
+ if isinstance(data, bytes):
129
+ return MultiByteStrDecoder(data).unicode_str.strip(str(strip_str))
130
+ elif isinstance(strip_str, bytes):
131
+ return data.strip(MultiByteStrDecoder(strip_str).unicode_str)
132
+
133
+ def __dequote(self, s: str) -> str:
134
+ if not self.dequote or not s:
135
+ return s
136
+
137
+ try:
138
+ if (s[0] == s[-1]) and s.startswith(("'", '"')):
139
+ if s.count(s[0]) == 2:
140
+ return s[1:-1]
141
+ except TypeError:
142
+ pass
143
+
144
+ return s
145
+
146
+ def __process_line_break(self, data: str) -> str:
147
+ lbh = self.line_break_handling
148
+
149
+ if lbh == LineBreakHandling.NOP:
150
+ return data
151
+
152
+ try:
153
+ if lbh == LineBreakHandling.REPLACE:
154
+ return _RE_LINE_BREAK.sub(self.line_break_repl, data)
155
+
156
+ if lbh == LineBreakHandling.ESCAPE:
157
+ return data.replace("\n", "\\n").replace("\r", "\\r")
158
+ except (TypeError, AttributeError):
159
+ return data
160
+
161
+ raise ValueError(f"unexpected line_break_handling: {lbh}")
162
+
163
+ def __escape_formula_injection(self, data: str) -> str:
164
+ if not self.is_escape_formula_injection:
165
+ return data
166
+
167
+ try:
168
+ if _RE_FORMULA_PREFIX.search(data):
169
+ return "'" + data
170
+ except (TypeError, AttributeError):
171
+ return data
172
+
173
+ return data
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/py.typed ADDED
File without changes
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dataproperty/typing.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections.abc import Mapping
2
+ from datetime import datetime
3
+ from decimal import Decimal
4
+ from typing import Any, Callable, Final, Optional, Union
5
+
6
+ from typepy import (
7
+ Bool,
8
+ DateTime,
9
+ Dictionary,
10
+ Infinity,
11
+ Integer,
12
+ IpAddress,
13
+ List,
14
+ Nan,
15
+ NoneType,
16
+ NullString,
17
+ RealNumber,
18
+ String,
19
+ Typecode,
20
+ )
21
+ from typepy.type import AbstractType
22
+
23
+
24
+ TypeHint = Optional[type[AbstractType]]
25
+ TransFunc = Callable[[Any], Any]
26
+ DateTimeFormatter = Callable[[datetime], str]
27
+
28
+ FloatType = Union[type[Decimal], type[float]]
29
+ StrictLevelMap = Mapping[Union[str, Typecode], int]
30
+ TypeValueMap = dict[Typecode, Union[float, str, Decimal, None]]
31
+
32
+ _type_hint_map: Final = {
33
+ # high frequently used types
34
+ "int": Integer,
35
+ "float": RealNumber,
36
+ "realnumber": RealNumber,
37
+ "str": String,
38
+ # low frequently used types
39
+ "bool": Bool,
40
+ "datetime": DateTime,
41
+ "dict": Dictionary,
42
+ "inf": Infinity,
43
+ "ip": IpAddress,
44
+ "list": List,
45
+ "nan": Nan,
46
+ "none": NoneType,
47
+ "nullstr": NullString,
48
+ }
49
+
50
+
51
+ def normalize_type_hint(type_hint: Union[str, TypeHint]) -> TypeHint:
52
+ if not type_hint:
53
+ return None
54
+
55
+ if not isinstance(type_hint, str):
56
+ return type_hint
57
+
58
+ type_hint = type_hint.strip().casefold()
59
+ for key, value in _type_hint_map.items():
60
+ if type_hint.startswith(key):
61
+ return value
62
+
63
+ raise ValueError(f"unknown typehint: {type_hint}")
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/LICENSE ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2004-2016 California Institute of Technology.
2
+ Copyright (c) 2016-2024 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
+
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/METADATA ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: dill
3
+ Version: 0.3.8
4
+ Summary: serialize all of Python
5
+ Home-page: https://github.com/uqfoundation/dill
6
+ Author: Mike McKerns
7
+ Author-email: mmckerns@uqfoundation.org
8
+ Maintainer: Mike McKerns
9
+ Maintainer-email: mmckerns@uqfoundation.org
10
+ License: BSD-3-Clause
11
+ Download-URL: https://pypi.org/project/dill/#files
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.8
24
+ Classifier: Programming Language :: Python :: 3.9
25
+ Classifier: Programming Language :: Python :: 3.10
26
+ Classifier: Programming Language :: Python :: 3.11
27
+ Classifier: Programming Language :: Python :: 3.12
28
+ Classifier: Programming Language :: Python :: Implementation :: CPython
29
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
30
+ Classifier: Topic :: Scientific/Engineering
31
+ Classifier: Topic :: Software Development
32
+ Requires-Python: >=3.8
33
+ Provides-Extra: graph
34
+ Requires-Dist: objgraph (>=1.7.2) ; extra == 'graph'
35
+ Provides-Extra: profile
36
+ Requires-Dist: gprof2dot (>=2022.7.29) ; extra == 'profile'
37
+ Provides-Extra: readline
38
+
39
+ -----------------------------
40
+ dill: serialize all of Python
41
+ -----------------------------
42
+
43
+ About Dill
44
+ ==========
45
+
46
+ ``dill`` extends Python's ``pickle`` module for serializing and de-serializing
47
+ Python objects to the majority of the built-in Python types. Serialization
48
+ is the process of converting an object to a byte stream, and the inverse
49
+ of which is converting a byte stream back to a Python object hierarchy.
50
+
51
+ ``dill`` provides the user the same interface as the ``pickle`` module, and
52
+ also includes some additional features. In addition to pickling Python
53
+ objects, ``dill`` provides the ability to save the state of an interpreter
54
+ session in a single command. Hence, it would be feasible to save an
55
+ interpreter session, close the interpreter, ship the pickled file to
56
+ another computer, open a new interpreter, unpickle the session and
57
+ thus continue from the 'saved' state of the original interpreter
58
+ session.
59
+
60
+ ``dill`` can be used to store Python objects to a file, but the primary
61
+ usage is to send Python objects across the network as a byte stream.
62
+ ``dill`` is quite flexible, and allows arbitrary user defined classes
63
+ and functions to be serialized. Thus ``dill`` is not intended to be
64
+ secure against erroneously or maliciously constructed data. It is
65
+ left to the user to decide whether the data they unpickle is from
66
+ a trustworthy source.
67
+
68
+ ``dill`` is part of ``pathos``, a Python framework for heterogeneous computing.
69
+ ``dill`` is in active development, so any user feedback, bug reports, comments,
70
+ or suggestions are highly appreciated. A list of issues is located at
71
+ https://github.com/uqfoundation/dill/issues, with a legacy list maintained at
72
+ https://uqfoundation.github.io/project/pathos/query.
73
+
74
+
75
+ Major Features
76
+ ==============
77
+
78
+ ``dill`` can pickle the following standard types:
79
+
80
+ - none, type, bool, int, float, complex, bytes, str,
81
+ - tuple, list, dict, file, buffer, builtin,
82
+ - Python classes, namedtuples, dataclasses, metaclasses,
83
+ - instances of classes,
84
+ - set, frozenset, array, functions, exceptions
85
+
86
+ ``dill`` can also pickle more 'exotic' standard types:
87
+
88
+ - functions with yields, nested functions, lambdas,
89
+ - cell, method, unboundmethod, module, code, methodwrapper,
90
+ - methoddescriptor, getsetdescriptor, memberdescriptor, wrapperdescriptor,
91
+ - dictproxy, slice, notimplemented, ellipsis, quit
92
+
93
+ ``dill`` cannot yet pickle these standard types:
94
+
95
+ - frame, generator, traceback
96
+
97
+ ``dill`` also provides the capability to:
98
+
99
+ - save and load Python interpreter sessions
100
+ - save and extract the source code from functions and classes
101
+ - interactively diagnose pickling errors
102
+
103
+
104
+ Current Release
105
+ ===============
106
+
107
+ The latest released version of ``dill`` is available from:
108
+
109
+ https://pypi.org/project/dill
110
+
111
+ ``dill`` is distributed under a 3-clause BSD license.
112
+
113
+
114
+ Development Version
115
+ ===================
116
+
117
+ You can get the latest development version with all the shiny new features at:
118
+
119
+ https://github.com/uqfoundation
120
+
121
+ If you have a new contribution, please submit a pull request.
122
+
123
+
124
+ Installation
125
+ ============
126
+
127
+ ``dill`` can be installed with ``pip``::
128
+
129
+ $ pip install dill
130
+
131
+ To optionally include the ``objgraph`` diagnostic tool in the install::
132
+
133
+ $ pip install dill[graph]
134
+
135
+ To optionally include the ``gprof2dot`` diagnostic tool in the install::
136
+
137
+ $ pip install dill[profile]
138
+
139
+ For windows users, to optionally install session history tools::
140
+
141
+ $ pip install dill[readline]
142
+
143
+
144
+ Requirements
145
+ ============
146
+
147
+ ``dill`` requires:
148
+
149
+ - ``python`` (or ``pypy``), **>=3.8**
150
+ - ``setuptools``, **>=42**
151
+
152
+ Optional requirements:
153
+
154
+ - ``objgraph``, **>=1.7.2**
155
+ - ``gprof2dot``, **>=2022.7.29**
156
+ - ``pyreadline``, **>=1.7.1** (on windows)
157
+
158
+
159
+ Basic Usage
160
+ ===========
161
+
162
+ ``dill`` is a drop-in replacement for ``pickle``. Existing code can be
163
+ updated to allow complete pickling using::
164
+
165
+ >>> import dill as pickle
166
+
167
+ or::
168
+
169
+ >>> from dill import dumps, loads
170
+
171
+ ``dumps`` converts the object to a unique byte string, and ``loads`` performs
172
+ the inverse operation::
173
+
174
+ >>> squared = lambda x: x**2
175
+ >>> loads(dumps(squared))(3)
176
+ 9
177
+
178
+ There are a number of options to control serialization which are provided
179
+ as keyword arguments to several ``dill`` functions:
180
+
181
+ * with *protocol*, the pickle protocol level can be set. This uses the
182
+ same value as the ``pickle`` module, *DEFAULT_PROTOCOL*.
183
+ * with *byref=True*, ``dill`` to behave a lot more like pickle with
184
+ certain objects (like modules) pickled by reference as opposed to
185
+ attempting to pickle the object itself.
186
+ * with *recurse=True*, objects referred to in the global dictionary are
187
+ recursively traced and pickled, instead of the default behavior of
188
+ attempting to store the entire global dictionary.
189
+ * with *fmode*, the contents of the file can be pickled along with the file
190
+ handle, which is useful if the object is being sent over the wire to a
191
+ remote system which does not have the original file on disk. Options are
192
+ *HANDLE_FMODE* for just the handle, *CONTENTS_FMODE* for the file content
193
+ and *FILE_FMODE* for content and handle.
194
+ * with *ignore=False*, objects reconstructed with types defined in the
195
+ top-level script environment use the existing type in the environment
196
+ rather than a possibly different reconstructed type.
197
+
198
+ The default serialization can also be set globally in *dill.settings*.
199
+ Thus, we can modify how ``dill`` handles references to the global dictionary
200
+ locally or globally::
201
+
202
+ >>> import dill.settings
203
+ >>> dumps(absolute) == dumps(absolute, recurse=True)
204
+ False
205
+ >>> dill.settings['recurse'] = True
206
+ >>> dumps(absolute) == dumps(absolute, recurse=True)
207
+ True
208
+
209
+ ``dill`` also includes source code inspection, as an alternate to pickling::
210
+
211
+ >>> import dill.source
212
+ >>> print(dill.source.getsource(squared))
213
+ squared = lambda x:x**2
214
+
215
+ To aid in debugging pickling issues, use *dill.detect* which provides
216
+ tools like pickle tracing::
217
+
218
+ >>> import dill.detect
219
+ >>> with dill.detect.trace():
220
+ >>> dumps(squared)
221
+ ┬ F1: <function <lambda> at 0x7fe074f8c280>
222
+ ├┬ F2: <function _create_function at 0x7fe074c49c10>
223
+ │└ # F2 [34 B]
224
+ ├┬ Co: <code object <lambda> at 0x7fe07501eb30, file "<stdin>", line 1>
225
+ │├┬ F2: <function _create_code at 0x7fe074c49ca0>
226
+ ││└ # F2 [19 B]
227
+ │└ # Co [87 B]
228
+ ├┬ D1: <dict object at 0x7fe0750d4680>
229
+ │└ # D1 [22 B]
230
+ ├┬ D2: <dict object at 0x7fe074c5a1c0>
231
+ │└ # D2 [2 B]
232
+ ├┬ D2: <dict object at 0x7fe074f903c0>
233
+ │├┬ D2: <dict object at 0x7fe074f8ebc0>
234
+ ││└ # D2 [2 B]
235
+ │└ # D2 [23 B]
236
+ └ # F1 [180 B]
237
+
238
+ With trace, we see how ``dill`` stored the lambda (``F1``) by first storing
239
+ ``_create_function``, the underlying code object (``Co``) and ``_create_code``
240
+ (which is used to handle code objects), then we handle the reference to
241
+ the global dict (``D2``) plus other dictionaries (``D1`` and ``D2``) that
242
+ save the lambda object's state. A ``#`` marks when the object is actually stored.
243
+
244
+
245
+ More Information
246
+ ================
247
+
248
+ Probably the best way to get started is to look at the documentation at
249
+ http://dill.rtfd.io. Also see ``dill.tests`` for a set of scripts that
250
+ demonstrate how ``dill`` can serialize different Python objects. You can
251
+ run the test suite with ``python -m dill.tests``. The contents of any
252
+ pickle file can be examined with ``undill``. As ``dill`` conforms to
253
+ the ``pickle`` interface, the examples and documentation found at
254
+ http://docs.python.org/library/pickle.html also apply to ``dill``
255
+ if one will ``import dill as pickle``. The source code is also generally
256
+ well documented, so further questions may be resolved by inspecting the
257
+ code itself. Please feel free to submit a ticket on github, or ask a
258
+ question on stackoverflow (**@Mike McKerns**).
259
+ If you would like to share how you use ``dill`` in your work, please send
260
+ an email (to **mmckerns at uqfoundation dot org**).
261
+
262
+
263
+ Citation
264
+ ========
265
+
266
+ If you use ``dill`` to do research that leads to publication, we ask that you
267
+ acknowledge use of ``dill`` by citing the following in your publication::
268
+
269
+ M.M. McKerns, L. Strand, T. Sullivan, A. Fang, M.A.G. Aivazis,
270
+ "Building a framework for predictive science", Proceedings of
271
+ the 10th Python in Science Conference, 2011;
272
+ http://arxiv.org/pdf/1202.1056
273
+
274
+ Michael McKerns and Michael Aivazis,
275
+ "pathos: a framework for heterogeneous computing", 2010- ;
276
+ https://uqfoundation.github.io/project/pathos
277
+
278
+ Please see https://uqfoundation.github.io/project/pathos or
279
+ http://arxiv.org/pdf/1202.1056 for further information.
280
+
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/RECORD ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ../../../bin/get_gprof,sha256=nW1i0ag0wM2lcIDa5fYOwpojD6X0W7bB9GRFI2tjmdY,2519
2
+ ../../../bin/get_objgraph,sha256=7Wmp6PX4aKI2yo8mM1o-elUEnSwjR1Rr38Q05p-x__c,1713
3
+ ../../../bin/undill,sha256=Hy4HhuvBvu6TH6sm6o7Fih70V16kmkN95G9ELONz7Fk,649
4
+ dill-0.3.8.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
5
+ dill-0.3.8.dist-info/LICENSE,sha256=UeiKI-eId86r1yfCGcel4z9l2pugOsT9KFupBKoc4is,1790
6
+ dill-0.3.8.dist-info/METADATA,sha256=UxkSs2cU8JyrJsV5kS0QR9crJ07hrUJS2RiIMQaC4ss,10106
7
+ dill-0.3.8.dist-info/RECORD,,
8
+ dill-0.3.8.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
9
+ dill-0.3.8.dist-info/top_level.txt,sha256=HLSIyYIjQzJiBvs3_-16ntezE3j6mWGTW0DT1xDd7X0,5
10
+ dill/__diff.py,sha256=kirMxzB7E8lfjo21M5oIf7if95ny0aWhYB790KMpN08,7143
11
+ dill/__info__.py,sha256=Kmel_yLTyH-hwNC5cVfzN-LV08AbS_AvSa2uwMeIQdk,10756
12
+ dill/__init__.py,sha256=j-Jxl3H6bxatS0h2f8ywWs7DChwk7B9ozuZQBVcjYGU,3798
13
+ dill/__pycache__/__diff.cpython-312.pyc,,
14
+ dill/__pycache__/__info__.cpython-312.pyc,,
15
+ dill/__pycache__/__init__.cpython-312.pyc,,
16
+ dill/__pycache__/_dill.cpython-312.pyc,,
17
+ dill/__pycache__/_objects.cpython-312.pyc,,
18
+ dill/__pycache__/_shims.cpython-312.pyc,,
19
+ dill/__pycache__/detect.cpython-312.pyc,,
20
+ dill/__pycache__/logger.cpython-312.pyc,,
21
+ dill/__pycache__/objtypes.cpython-312.pyc,,
22
+ dill/__pycache__/pointers.cpython-312.pyc,,
23
+ dill/__pycache__/session.cpython-312.pyc,,
24
+ dill/__pycache__/settings.cpython-312.pyc,,
25
+ dill/__pycache__/source.cpython-312.pyc,,
26
+ dill/__pycache__/temp.cpython-312.pyc,,
27
+ dill/_dill.py,sha256=3Eo6gKj1sODJjgPgYNT8TU-YL6QNQ7rIeWPUVnRzyqQ,88548
28
+ dill/_objects.py,sha256=dPlUXzQIh8CA0fMy9NMbwwLGUPmXe5H8MdQtRWB1b_M,19605
29
+ dill/_shims.py,sha256=IuzQcyPET5VWmWMoSGStieoedvNXlb5suDpa4bykTbQ,6635
30
+ dill/detect.py,sha256=Mb-PfCxn1mg0l3TmHXyPNVEc4n3fuxc_nue6eL3-q_o,11114
31
+ dill/logger.py,sha256=YS5ZloAOKjJRZaOBRCaMUDWmWVQZcicvbXVSrz8L8XU,11134
32
+ dill/objtypes.py,sha256=BamGH3BEM6lLlxisuvXcGjsCRLNeoLs4_rFZrM5r2yM,736
33
+ dill/pointers.py,sha256=vnQzjwGtKMGnmbdYRXRWNLMyceNPSw4f7UpvwCXLYbE,4467
34
+ dill/session.py,sha256=NvCWpoP9r_rGBL2pOwwxOri8mFly5KlIWG3GwkBFnc0,23525
35
+ dill/settings.py,sha256=7I3yvSpPKstOqpoW2gv3X77kXK-hZlqCnF7nJUGhxTY,630
36
+ dill/source.py,sha256=DWfIxcBjpjbbKYz2DstV9kRdjajBdZLOcLXfsZsPo9U,45121
37
+ dill/temp.py,sha256=KJUry4t0UjQCh5t4LXcxNyMF_uOGHwcjTuNYTJD9qdA,8027
38
+ dill/tests/__init__.py,sha256=Gx-chVB-l-e7ncsGp2zF4BimTjbUyO7BY7RkrO835vY,479
39
+ dill/tests/__main__.py,sha256=fHhioQwcOvTPlf1RM_wVQ0Y3ndETWJOuXJQ2rVtqliA,899
40
+ dill/tests/__pycache__/__init__.cpython-312.pyc,,
41
+ dill/tests/__pycache__/__main__.cpython-312.pyc,,
42
+ dill/tests/__pycache__/test_abc.cpython-312.pyc,,
43
+ dill/tests/__pycache__/test_check.cpython-312.pyc,,
44
+ dill/tests/__pycache__/test_classdef.cpython-312.pyc,,
45
+ dill/tests/__pycache__/test_dataclasses.cpython-312.pyc,,
46
+ dill/tests/__pycache__/test_detect.cpython-312.pyc,,
47
+ dill/tests/__pycache__/test_dictviews.cpython-312.pyc,,
48
+ dill/tests/__pycache__/test_diff.cpython-312.pyc,,
49
+ dill/tests/__pycache__/test_extendpickle.cpython-312.pyc,,
50
+ dill/tests/__pycache__/test_fglobals.cpython-312.pyc,,
51
+ dill/tests/__pycache__/test_file.cpython-312.pyc,,
52
+ dill/tests/__pycache__/test_functions.cpython-312.pyc,,
53
+ dill/tests/__pycache__/test_functors.cpython-312.pyc,,
54
+ dill/tests/__pycache__/test_logger.cpython-312.pyc,,
55
+ dill/tests/__pycache__/test_mixins.cpython-312.pyc,,
56
+ dill/tests/__pycache__/test_module.cpython-312.pyc,,
57
+ dill/tests/__pycache__/test_moduledict.cpython-312.pyc,,
58
+ dill/tests/__pycache__/test_nested.cpython-312.pyc,,
59
+ dill/tests/__pycache__/test_objects.cpython-312.pyc,,
60
+ dill/tests/__pycache__/test_properties.cpython-312.pyc,,
61
+ dill/tests/__pycache__/test_pycapsule.cpython-312.pyc,,
62
+ dill/tests/__pycache__/test_recursive.cpython-312.pyc,,
63
+ dill/tests/__pycache__/test_registered.cpython-312.pyc,,
64
+ dill/tests/__pycache__/test_restricted.cpython-312.pyc,,
65
+ dill/tests/__pycache__/test_selected.cpython-312.pyc,,
66
+ dill/tests/__pycache__/test_session.cpython-312.pyc,,
67
+ dill/tests/__pycache__/test_source.cpython-312.pyc,,
68
+ dill/tests/__pycache__/test_temp.cpython-312.pyc,,
69
+ dill/tests/__pycache__/test_weakref.cpython-312.pyc,,
70
+ dill/tests/test_abc.py,sha256=BSjSKKCQ5_iPfFxAd0yBq4KSAJxelrlC3IzoAhjd1C4,4227
71
+ dill/tests/test_check.py,sha256=4F5gkX6zxY7C5sD2_0Tkqf3T3jmQl0K15FOxYUTZQl0,1396
72
+ dill/tests/test_classdef.py,sha256=fI3fVk4SlsjNMMs5RfU6DUCaxpP7YYRjvLZ2nhXMHuc,8600
73
+ dill/tests/test_dataclasses.py,sha256=yKjFuG24ymLtjk-sZZdhvNY7aDqerTDpMcfi_eV4ft0,890
74
+ dill/tests/test_detect.py,sha256=sE9THufHXCDysBPQ4QkN5DHn6DaIldVRAEciseIRH08,4083
75
+ dill/tests/test_dictviews.py,sha256=Jhol0cQWPwoQrp7OPxGhU8FNRX2GgfFp9fTahCvQEPA,1337
76
+ dill/tests/test_diff.py,sha256=5VIWf2fpV6auLHNfzkHLTrgx6AJBlE2xe5Wanfmq8TM,2667
77
+ dill/tests/test_extendpickle.py,sha256=gONrMBHO94Edhnqm1wo49hgzwmaxHs7L-86Hs-7albY,1315
78
+ dill/tests/test_fglobals.py,sha256=DCvdojmKcLN_X9vX4Qe1FbsqjeoJK-wsY2uJwBfNFro,1676
79
+ dill/tests/test_file.py,sha256=jUU2h8qaDOIe1mn_Ng7wqCZcd7Ucx3TAaI-K_90_Tbk,13578
80
+ dill/tests/test_functions.py,sha256=-mqTpUbzRu8GynjBGD25dRDm8qInIe07sRZmCcA_iXY,4267
81
+ dill/tests/test_functors.py,sha256=7rx9wLmrgFwF0gUm_-SGOISPYSok0XjmrQ-jFMRt6gs,930
82
+ dill/tests/test_logger.py,sha256=D9zGRaA-CEadG13orPS_D4gPVZlkqXf9Zu8wn2oMiYc,2385
83
+ dill/tests/test_mixins.py,sha256=YtB24BjodooLj85ijFbAxiM7LlFQZAUL8RQVx9vIAwY,4007
84
+ dill/tests/test_module.py,sha256=KLl_gZJJqDY7S_bD5wCqKL8JQCS0MDMoipVQSDfASlo,1943
85
+ dill/tests/test_moduledict.py,sha256=faXG6-5AcmCfP3xe2FYGOUdSosU-9TWnKU_ZVqPDaxY,1182
86
+ dill/tests/test_nested.py,sha256=ViWiOrChLZktS0z6qyKqMxDdTuy9kAX4qMgH_OreMcc,3146
87
+ dill/tests/test_objects.py,sha256=pPAth0toC_UWztuKHC7NZlsRBb0g_gSAt70UbUtXEXo,1931
88
+ dill/tests/test_properties.py,sha256=h35c-lYir1JG6oLPtrA0eYE0xoSohIimsA3yIfRw6yA,1346
89
+ dill/tests/test_pycapsule.py,sha256=EXFyB6g1Wx9O9LM6StIeUKhrhln4_hou1xrtGwkt4Cw,1417
90
+ dill/tests/test_recursive.py,sha256=bfr-BsK1Xu0PU7l2srHsDXdY2l1LeM3L3w7NraXO0cc,4182
91
+ dill/tests/test_registered.py,sha256=J3oku053VfdJgYh4Z5_kyFRf-C52JglIzjcyxEaYOhk,1573
92
+ dill/tests/test_restricted.py,sha256=xLMIae8sYJksAj9hKKyHFHIL8vtbGpFeOULz59snYM4,783
93
+ dill/tests/test_selected.py,sha256=Hp-AAd6Qp5FJZ-vY_Bbejo5Rg6xFstec5QkSg5D7Aac,3218
94
+ dill/tests/test_session.py,sha256=KoSPvs4c4VJ8mFMF7EUlD_3GwcOhhipt9fqHr--Go-4,10161
95
+ dill/tests/test_source.py,sha256=wZTYBbpzUwj3Mz5OjrHQKfskaVVwuy2UQDg5p2wLbT4,6036
96
+ dill/tests/test_temp.py,sha256=F_7nJkSetLIBSAYMw1-hYh03iVrEYwGs-4GIUzoBOfY,2619
97
+ dill/tests/test_weakref.py,sha256=mrjZP5aPtUP1wBD6ibPsDsfI9ffmq_Ykt7ltoodi5Lg,1602
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.37.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill-0.3.8.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ dill
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/__diff.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2016 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+
9
+ """
10
+ Module to show if an object has changed since it was memorised
11
+ """
12
+
13
+ import builtins
14
+ import os
15
+ import sys
16
+ import types
17
+ try:
18
+ import numpy
19
+ HAS_NUMPY = True
20
+ except ImportError:
21
+ HAS_NUMPY = False
22
+
23
+ # pypy doesn't use reference counting
24
+ getrefcount = getattr(sys, 'getrefcount', lambda x:0)
25
+
26
+ # memo of objects indexed by id to a tuple (attributes, sequence items)
27
+ # attributes is a dict indexed by attribute name to attribute id
28
+ # sequence items is either a list of ids, of a dictionary of keys to ids
29
+ memo = {}
30
+ id_to_obj = {}
31
+ # types that cannot have changing attributes
32
+ builtins_types = set((str, list, dict, set, frozenset, int))
33
+ dont_memo = set(id(i) for i in (memo, sys.modules, sys.path_importer_cache,
34
+ os.environ, id_to_obj))
35
+
36
+
37
+ def get_attrs(obj):
38
+ """
39
+ Gets all the attributes of an object though its __dict__ or return None
40
+ """
41
+ if type(obj) in builtins_types \
42
+ or type(obj) is type and obj in builtins_types:
43
+ return
44
+ return getattr(obj, '__dict__', None)
45
+
46
+
47
+ def get_seq(obj, cache={str: False, frozenset: False, list: True, set: True,
48
+ dict: True, tuple: True, type: False,
49
+ types.ModuleType: False, types.FunctionType: False,
50
+ types.BuiltinFunctionType: False}):
51
+ """
52
+ Gets all the items in a sequence or return None
53
+ """
54
+ try:
55
+ o_type = obj.__class__
56
+ except AttributeError:
57
+ o_type = type(obj)
58
+ hsattr = hasattr
59
+ if o_type in cache:
60
+ if cache[o_type]:
61
+ if hsattr(obj, "copy"):
62
+ return obj.copy()
63
+ return obj
64
+ elif HAS_NUMPY and o_type in (numpy.ndarray, numpy.ma.core.MaskedConstant):
65
+ if obj.shape and obj.size:
66
+ return obj
67
+ else:
68
+ return []
69
+ elif hsattr(obj, "__contains__") and hsattr(obj, "__iter__") \
70
+ and hsattr(obj, "__len__") and hsattr(o_type, "__contains__") \
71
+ and hsattr(o_type, "__iter__") and hsattr(o_type, "__len__"):
72
+ cache[o_type] = True
73
+ if hsattr(obj, "copy"):
74
+ return obj.copy()
75
+ return obj
76
+ else:
77
+ cache[o_type] = False
78
+ return None
79
+
80
+
81
+ def memorise(obj, force=False):
82
+ """
83
+ Adds an object to the memo, and recursively adds all the objects
84
+ attributes, and if it is a container, its items. Use force=True to update
85
+ an object already in the memo. Updating is not recursively done.
86
+ """
87
+ obj_id = id(obj)
88
+ if obj_id in memo and not force or obj_id in dont_memo:
89
+ return
90
+ id_ = id
91
+ g = get_attrs(obj)
92
+ if g is None:
93
+ attrs_id = None
94
+ else:
95
+ attrs_id = dict((key,id_(value)) for key, value in g.items())
96
+
97
+ s = get_seq(obj)
98
+ if s is None:
99
+ seq_id = None
100
+ elif hasattr(s, "items"):
101
+ seq_id = dict((id_(key),id_(value)) for key, value in s.items())
102
+ elif not hasattr(s, "__len__"): #XXX: avoid TypeError from unexpected case
103
+ seq_id = None
104
+ else:
105
+ seq_id = [id_(i) for i in s]
106
+
107
+ memo[obj_id] = attrs_id, seq_id
108
+ id_to_obj[obj_id] = obj
109
+ mem = memorise
110
+ if g is not None:
111
+ [mem(value) for key, value in g.items()]
112
+
113
+ if s is not None:
114
+ if hasattr(s, "items"):
115
+ [(mem(key), mem(item))
116
+ for key, item in s.items()]
117
+ else:
118
+ if hasattr(s, '__len__'):
119
+ [mem(item) for item in s]
120
+ else: mem(s)
121
+
122
+
123
+ def release_gone():
124
+ itop, mp, src = id_to_obj.pop, memo.pop, getrefcount
125
+ [(itop(id_), mp(id_)) for id_, obj in list(id_to_obj.items())
126
+ if src(obj) < 4] #XXX: correct for pypy?
127
+
128
+
129
+ def whats_changed(obj, seen=None, simple=False, first=True):
130
+ """
131
+ Check an object against the memo. Returns a list in the form
132
+ (attribute changes, container changed). Attribute changes is a dict of
133
+ attribute name to attribute value. container changed is a boolean.
134
+ If simple is true, just returns a boolean. None for either item means
135
+ that it has not been checked yet
136
+ """
137
+ # Special cases
138
+ if first:
139
+ # ignore the _ variable, which only appears in interactive sessions
140
+ if "_" in builtins.__dict__:
141
+ del builtins._
142
+ if seen is None:
143
+ seen = {}
144
+
145
+ obj_id = id(obj)
146
+
147
+ if obj_id in seen:
148
+ if simple:
149
+ return any(seen[obj_id])
150
+ return seen[obj_id]
151
+
152
+ # Safety checks
153
+ if obj_id in dont_memo:
154
+ seen[obj_id] = [{}, False]
155
+ if simple:
156
+ return False
157
+ return seen[obj_id]
158
+ elif obj_id not in memo:
159
+ if simple:
160
+ return True
161
+ else:
162
+ raise RuntimeError("Object not memorised " + str(obj))
163
+
164
+ seen[obj_id] = ({}, False)
165
+
166
+ chngd = whats_changed
167
+ id_ = id
168
+
169
+ # compare attributes
170
+ attrs = get_attrs(obj)
171
+ if attrs is None:
172
+ changed = {}
173
+ else:
174
+ obj_attrs = memo[obj_id][0]
175
+ obj_get = obj_attrs.get
176
+ changed = dict((key,None) for key in obj_attrs if key not in attrs)
177
+ for key, o in attrs.items():
178
+ if id_(o) != obj_get(key, None) or chngd(o, seen, True, False):
179
+ changed[key] = o
180
+
181
+ # compare sequence
182
+ items = get_seq(obj)
183
+ seq_diff = False
184
+ if (items is not None) and (hasattr(items, '__len__')):
185
+ obj_seq = memo[obj_id][1]
186
+ if (len(items) != len(obj_seq)):
187
+ seq_diff = True
188
+ elif hasattr(obj, "items"): # dict type obj
189
+ obj_get = obj_seq.get
190
+ for key, item in items.items():
191
+ if id_(item) != obj_get(id_(key)) \
192
+ or chngd(key, seen, True, False) \
193
+ or chngd(item, seen, True, False):
194
+ seq_diff = True
195
+ break
196
+ else:
197
+ for i, j in zip(items, obj_seq): # list type obj
198
+ if id_(i) != j or chngd(i, seen, True, False):
199
+ seq_diff = True
200
+ break
201
+ seen[obj_id] = changed, seq_diff
202
+ if simple:
203
+ return changed or seq_diff
204
+ return changed, seq_diff
205
+
206
+
207
+ def has_changed(*args, **kwds):
208
+ kwds['simple'] = True # ignore simple if passed in
209
+ return whats_changed(*args, **kwds)
210
+
211
+ __import__ = __import__
212
+
213
+
214
+ def _imp(*args, **kwds):
215
+ """
216
+ Replaces the default __import__, to allow a module to be memorised
217
+ before the user can change it
218
+ """
219
+ before = set(sys.modules.keys())
220
+ mod = __import__(*args, **kwds)
221
+ after = set(sys.modules.keys()).difference(before)
222
+ for m in after:
223
+ memorise(sys.modules[m])
224
+ return mod
225
+
226
+ builtins.__import__ = _imp
227
+ if hasattr(builtins, "_"):
228
+ del builtins._
229
+
230
+ # memorise all already imported modules. This implies that this must be
231
+ # imported first for any changes to be recorded
232
+ for mod in list(sys.modules.values()):
233
+ memorise(mod)
234
+ release_gone()
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/__info__.py ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2024 The Uncertainty Quantification Foundation.
5
+ # License: 3-clause BSD. The full license text is available at:
6
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
7
+ '''
8
+ -----------------------------
9
+ dill: serialize all of Python
10
+ -----------------------------
11
+
12
+ About Dill
13
+ ==========
14
+
15
+ ``dill`` extends Python's ``pickle`` module for serializing and de-serializing
16
+ Python objects to the majority of the built-in Python types. Serialization
17
+ is the process of converting an object to a byte stream, and the inverse
18
+ of which is converting a byte stream back to a Python object hierarchy.
19
+
20
+ ``dill`` provides the user the same interface as the ``pickle`` module, and
21
+ also includes some additional features. In addition to pickling Python
22
+ objects, ``dill`` provides the ability to save the state of an interpreter
23
+ session in a single command. Hence, it would be feasible to save an
24
+ interpreter session, close the interpreter, ship the pickled file to
25
+ another computer, open a new interpreter, unpickle the session and
26
+ thus continue from the 'saved' state of the original interpreter
27
+ session.
28
+
29
+ ``dill`` can be used to store Python objects to a file, but the primary
30
+ usage is to send Python objects across the network as a byte stream.
31
+ ``dill`` is quite flexible, and allows arbitrary user defined classes
32
+ and functions to be serialized. Thus ``dill`` is not intended to be
33
+ secure against erroneously or maliciously constructed data. It is
34
+ left to the user to decide whether the data they unpickle is from
35
+ a trustworthy source.
36
+
37
+ ``dill`` is part of ``pathos``, a Python framework for heterogeneous computing.
38
+ ``dill`` is in active development, so any user feedback, bug reports, comments,
39
+ or suggestions are highly appreciated. A list of issues is located at
40
+ https://github.com/uqfoundation/dill/issues, with a legacy list maintained at
41
+ https://uqfoundation.github.io/project/pathos/query.
42
+
43
+
44
+ Major Features
45
+ ==============
46
+
47
+ ``dill`` can pickle the following standard types:
48
+
49
+ - none, type, bool, int, float, complex, bytes, str,
50
+ - tuple, list, dict, file, buffer, builtin,
51
+ - Python classes, namedtuples, dataclasses, metaclasses,
52
+ - instances of classes,
53
+ - set, frozenset, array, functions, exceptions
54
+
55
+ ``dill`` can also pickle more 'exotic' standard types:
56
+
57
+ - functions with yields, nested functions, lambdas,
58
+ - cell, method, unboundmethod, module, code, methodwrapper,
59
+ - methoddescriptor, getsetdescriptor, memberdescriptor, wrapperdescriptor,
60
+ - dictproxy, slice, notimplemented, ellipsis, quit
61
+
62
+ ``dill`` cannot yet pickle these standard types:
63
+
64
+ - frame, generator, traceback
65
+
66
+ ``dill`` also provides the capability to:
67
+
68
+ - save and load Python interpreter sessions
69
+ - save and extract the source code from functions and classes
70
+ - interactively diagnose pickling errors
71
+
72
+
73
+ Current Release
74
+ ===============
75
+
76
+ The latest released version of ``dill`` is available from:
77
+
78
+ https://pypi.org/project/dill
79
+
80
+ ``dill`` is distributed under a 3-clause BSD license.
81
+
82
+
83
+ Development Version
84
+ ===================
85
+
86
+ You can get the latest development version with all the shiny new features at:
87
+
88
+ https://github.com/uqfoundation
89
+
90
+ If you have a new contribution, please submit a pull request.
91
+
92
+
93
+ Installation
94
+ ============
95
+
96
+ ``dill`` can be installed with ``pip``::
97
+
98
+ $ pip install dill
99
+
100
+ To optionally include the ``objgraph`` diagnostic tool in the install::
101
+
102
+ $ pip install dill[graph]
103
+
104
+ To optionally include the ``gprof2dot`` diagnostic tool in the install::
105
+
106
+ $ pip install dill[profile]
107
+
108
+ For windows users, to optionally install session history tools::
109
+
110
+ $ pip install dill[readline]
111
+
112
+
113
+ Requirements
114
+ ============
115
+
116
+ ``dill`` requires:
117
+
118
+ - ``python`` (or ``pypy``), **>=3.8**
119
+ - ``setuptools``, **>=42**
120
+
121
+ Optional requirements:
122
+
123
+ - ``objgraph``, **>=1.7.2**
124
+ - ``gprof2dot``, **>=2022.7.29**
125
+ - ``pyreadline``, **>=1.7.1** (on windows)
126
+
127
+
128
+ Basic Usage
129
+ ===========
130
+
131
+ ``dill`` is a drop-in replacement for ``pickle``. Existing code can be
132
+ updated to allow complete pickling using::
133
+
134
+ >>> import dill as pickle
135
+
136
+ or::
137
+
138
+ >>> from dill import dumps, loads
139
+
140
+ ``dumps`` converts the object to a unique byte string, and ``loads`` performs
141
+ the inverse operation::
142
+
143
+ >>> squared = lambda x: x**2
144
+ >>> loads(dumps(squared))(3)
145
+ 9
146
+
147
+ There are a number of options to control serialization which are provided
148
+ as keyword arguments to several ``dill`` functions:
149
+
150
+ * with *protocol*, the pickle protocol level can be set. This uses the
151
+ same value as the ``pickle`` module, *DEFAULT_PROTOCOL*.
152
+ * with *byref=True*, ``dill`` to behave a lot more like pickle with
153
+ certain objects (like modules) pickled by reference as opposed to
154
+ attempting to pickle the object itself.
155
+ * with *recurse=True*, objects referred to in the global dictionary are
156
+ recursively traced and pickled, instead of the default behavior of
157
+ attempting to store the entire global dictionary.
158
+ * with *fmode*, the contents of the file can be pickled along with the file
159
+ handle, which is useful if the object is being sent over the wire to a
160
+ remote system which does not have the original file on disk. Options are
161
+ *HANDLE_FMODE* for just the handle, *CONTENTS_FMODE* for the file content
162
+ and *FILE_FMODE* for content and handle.
163
+ * with *ignore=False*, objects reconstructed with types defined in the
164
+ top-level script environment use the existing type in the environment
165
+ rather than a possibly different reconstructed type.
166
+
167
+ The default serialization can also be set globally in *dill.settings*.
168
+ Thus, we can modify how ``dill`` handles references to the global dictionary
169
+ locally or globally::
170
+
171
+ >>> import dill.settings
172
+ >>> dumps(absolute) == dumps(absolute, recurse=True)
173
+ False
174
+ >>> dill.settings['recurse'] = True
175
+ >>> dumps(absolute) == dumps(absolute, recurse=True)
176
+ True
177
+
178
+ ``dill`` also includes source code inspection, as an alternate to pickling::
179
+
180
+ >>> import dill.source
181
+ >>> print(dill.source.getsource(squared))
182
+ squared = lambda x:x**2
183
+
184
+ To aid in debugging pickling issues, use *dill.detect* which provides
185
+ tools like pickle tracing::
186
+
187
+ >>> import dill.detect
188
+ >>> with dill.detect.trace():
189
+ >>> dumps(squared)
190
+ ┬ F1: <function <lambda> at 0x7fe074f8c280>
191
+ ├┬ F2: <function _create_function at 0x7fe074c49c10>
192
+ │└ # F2 [34 B]
193
+ ├┬ Co: <code object <lambda> at 0x7fe07501eb30, file "<stdin>", line 1>
194
+ │├┬ F2: <function _create_code at 0x7fe074c49ca0>
195
+ ││└ # F2 [19 B]
196
+ │└ # Co [87 B]
197
+ ├┬ D1: <dict object at 0x7fe0750d4680>
198
+ │└ # D1 [22 B]
199
+ ├┬ D2: <dict object at 0x7fe074c5a1c0>
200
+ │└ # D2 [2 B]
201
+ ├┬ D2: <dict object at 0x7fe074f903c0>
202
+ │├┬ D2: <dict object at 0x7fe074f8ebc0>
203
+ ││└ # D2 [2 B]
204
+ │└ # D2 [23 B]
205
+ └ # F1 [180 B]
206
+
207
+ With trace, we see how ``dill`` stored the lambda (``F1``) by first storing
208
+ ``_create_function``, the underlying code object (``Co``) and ``_create_code``
209
+ (which is used to handle code objects), then we handle the reference to
210
+ the global dict (``D2``) plus other dictionaries (``D1`` and ``D2``) that
211
+ save the lambda object's state. A ``#`` marks when the object is actually stored.
212
+
213
+
214
+ More Information
215
+ ================
216
+
217
+ Probably the best way to get started is to look at the documentation at
218
+ http://dill.rtfd.io. Also see ``dill.tests`` for a set of scripts that
219
+ demonstrate how ``dill`` can serialize different Python objects. You can
220
+ run the test suite with ``python -m dill.tests``. The contents of any
221
+ pickle file can be examined with ``undill``. As ``dill`` conforms to
222
+ the ``pickle`` interface, the examples and documentation found at
223
+ http://docs.python.org/library/pickle.html also apply to ``dill``
224
+ if one will ``import dill as pickle``. The source code is also generally
225
+ well documented, so further questions may be resolved by inspecting the
226
+ code itself. Please feel free to submit a ticket on github, or ask a
227
+ question on stackoverflow (**@Mike McKerns**).
228
+ If you would like to share how you use ``dill`` in your work, please send
229
+ an email (to **mmckerns at uqfoundation dot org**).
230
+
231
+
232
+ Citation
233
+ ========
234
+
235
+ If you use ``dill`` to do research that leads to publication, we ask that you
236
+ acknowledge use of ``dill`` by citing the following in your publication::
237
+
238
+ M.M. McKerns, L. Strand, T. Sullivan, A. Fang, M.A.G. Aivazis,
239
+ "Building a framework for predictive science", Proceedings of
240
+ the 10th Python in Science Conference, 2011;
241
+ http://arxiv.org/pdf/1202.1056
242
+
243
+ Michael McKerns and Michael Aivazis,
244
+ "pathos: a framework for heterogeneous computing", 2010- ;
245
+ https://uqfoundation.github.io/project/pathos
246
+
247
+ Please see https://uqfoundation.github.io/project/pathos or
248
+ http://arxiv.org/pdf/1202.1056 for further information.
249
+
250
+ '''
251
+
252
+ __version__ = '0.3.8'
253
+ __author__ = 'Mike McKerns'
254
+
255
+ __license__ = '''
256
+ Copyright (c) 2004-2016 California Institute of Technology.
257
+ Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
258
+ All rights reserved.
259
+
260
+ This software is available subject to the conditions and terms laid
261
+ out below. By downloading and using this software you are agreeing
262
+ to the following conditions.
263
+
264
+ Redistribution and use in source and binary forms, with or without
265
+ modification, are permitted provided that the following conditions
266
+ are met:
267
+
268
+ - Redistributions of source code must retain the above copyright
269
+ notice, this list of conditions and the following disclaimer.
270
+
271
+ - Redistributions in binary form must reproduce the above copyright
272
+ notice, this list of conditions and the following disclaimer in the
273
+ documentation and/or other materials provided with the distribution.
274
+
275
+ - Neither the names of the copyright holders nor the names of any of
276
+ the contributors may be used to endorse or promote products derived
277
+ from this software without specific prior written permission.
278
+
279
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
280
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
281
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
282
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
283
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
284
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
285
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
286
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
287
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
288
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
289
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
290
+
291
+ '''
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/__init__.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2016 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+
9
+ # author, version, license, and long description
10
+ try: # the package is installed
11
+ from .__info__ import __version__, __author__, __doc__, __license__
12
+ except: # pragma: no cover
13
+ import os
14
+ import sys
15
+ parent = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
16
+ sys.path.append(parent)
17
+ # get distribution meta info
18
+ from version import (__version__, __author__,
19
+ get_license_text, get_readme_as_rst)
20
+ __license__ = get_license_text(os.path.join(parent, 'LICENSE'))
21
+ __license__ = "\n%s" % __license__
22
+ __doc__ = get_readme_as_rst(os.path.join(parent, 'README.md'))
23
+ del os, sys, parent, get_license_text, get_readme_as_rst
24
+
25
+
26
+ from ._dill import (
27
+ dump, dumps, load, loads, copy,
28
+ Pickler, Unpickler, register, pickle, pickles, check,
29
+ DEFAULT_PROTOCOL, HIGHEST_PROTOCOL, HANDLE_FMODE, CONTENTS_FMODE, FILE_FMODE,
30
+ PickleError, PickleWarning, PicklingError, PicklingWarning, UnpicklingError,
31
+ UnpicklingWarning,
32
+ )
33
+ from .session import (
34
+ dump_module, load_module, load_module_asdict,
35
+ dump_session, load_session # backward compatibility
36
+ )
37
+ from . import detect, logger, session, source, temp
38
+
39
+ # get global settings
40
+ from .settings import settings
41
+
42
+ # make sure "trace" is turned off
43
+ logger.trace(False)
44
+
45
+ objects = {}
46
+ # local import of dill._objects
47
+ #from . import _objects
48
+ #objects.update(_objects.succeeds)
49
+ #del _objects
50
+
51
+ # local import of dill.objtypes
52
+ from . import objtypes as types
53
+
54
+ def load_types(pickleable=True, unpickleable=True):
55
+ """load pickleable and/or unpickleable types to ``dill.types``
56
+
57
+ ``dill.types`` is meant to mimic the ``types`` module, providing a
58
+ registry of object types. By default, the module is empty (for import
59
+ speed purposes). Use the ``load_types`` function to load selected object
60
+ types to the ``dill.types`` module.
61
+
62
+ Args:
63
+ pickleable (bool, default=True): if True, load pickleable types.
64
+ unpickleable (bool, default=True): if True, load unpickleable types.
65
+
66
+ Returns:
67
+ None
68
+ """
69
+ from importlib import reload
70
+ # local import of dill.objects
71
+ from . import _objects
72
+ if pickleable:
73
+ objects.update(_objects.succeeds)
74
+ else:
75
+ [objects.pop(obj,None) for obj in _objects.succeeds]
76
+ if unpickleable:
77
+ objects.update(_objects.failures)
78
+ else:
79
+ [objects.pop(obj,None) for obj in _objects.failures]
80
+ objects.update(_objects.registered)
81
+ del _objects
82
+ # reset contents of types to 'empty'
83
+ [types.__dict__.pop(obj) for obj in list(types.__dict__.keys()) \
84
+ if obj.find('Type') != -1]
85
+ # add corresponding types from objects to types
86
+ reload(types)
87
+
88
+ def extend(use_dill=True):
89
+ '''add (or remove) dill types to/from the pickle registry
90
+
91
+ by default, ``dill`` populates its types to ``pickle.Pickler.dispatch``.
92
+ Thus, all ``dill`` types are available upon calling ``'import pickle'``.
93
+ To drop all ``dill`` types from the ``pickle`` dispatch, *use_dill=False*.
94
+
95
+ Args:
96
+ use_dill (bool, default=True): if True, extend the dispatch table.
97
+
98
+ Returns:
99
+ None
100
+ '''
101
+ from ._dill import _revert_extension, _extend
102
+ if use_dill: _extend()
103
+ else: _revert_extension()
104
+ return
105
+
106
+ extend()
107
+
108
+
109
+ def license():
110
+ """print license"""
111
+ print (__license__)
112
+ return
113
+
114
+ def citation():
115
+ """print citation"""
116
+ print (__doc__[-491:-118])
117
+ return
118
+
119
+ # end of file
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/_dill.py ADDED
@@ -0,0 +1,2198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2015 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+ """
9
+ dill: a utility for serialization of python objects
10
+
11
+ The primary functions in `dill` are :func:`dump` and
12
+ :func:`dumps` for serialization ("pickling") to a
13
+ file or to a string, respectively, and :func:`load`
14
+ and :func:`loads` for deserialization ("unpickling"),
15
+ similarly, from a file or from a string. Other notable
16
+ functions are :func:`~dill.dump_module` and
17
+ :func:`~dill.load_module`, which are used to save and
18
+ restore module objects, including an intepreter session.
19
+
20
+ Based on code written by Oren Tirosh and Armin Ronacher.
21
+ Extended to a (near) full set of the builtin types (in types module),
22
+ and coded to the pickle interface, by <mmckerns@caltech.edu>.
23
+ Initial port to python3 by Jonathan Dobson, continued by mmckerns.
24
+ Tested against "all" python types (Std. Lib. CH 1-15 @ 2.7) by mmckerns.
25
+ Tested against CH16+ Std. Lib. ... TBD.
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ __all__ = [
31
+ 'dump','dumps','load','loads','copy',
32
+ 'Pickler','Unpickler','register','pickle','pickles','check',
33
+ 'DEFAULT_PROTOCOL','HIGHEST_PROTOCOL','HANDLE_FMODE','CONTENTS_FMODE','FILE_FMODE',
34
+ 'PickleError','PickleWarning','PicklingError','PicklingWarning','UnpicklingError',
35
+ 'UnpicklingWarning',
36
+ ]
37
+
38
+ __module__ = 'dill'
39
+
40
+ import warnings
41
+ from .logger import adapter as logger
42
+ from .logger import trace as _trace
43
+ log = logger # backward compatibility (see issue #582)
44
+
45
+ import os
46
+ import sys
47
+ diff = None
48
+ _use_diff = False
49
+ OLD38 = (sys.hexversion < 0x3080000)
50
+ OLD39 = (sys.hexversion < 0x3090000)
51
+ OLD310 = (sys.hexversion < 0x30a0000)
52
+ OLD312a7 = (sys.hexversion < 0x30c00a7)
53
+ #XXX: get types from .objtypes ?
54
+ import builtins as __builtin__
55
+ from pickle import _Pickler as StockPickler, Unpickler as StockUnpickler
56
+ from pickle import GLOBAL, POP
57
+ from _thread import LockType
58
+ from _thread import RLock as RLockType
59
+ #from io import IOBase
60
+ from types import CodeType, FunctionType, MethodType, GeneratorType, \
61
+ TracebackType, FrameType, ModuleType, BuiltinMethodType
62
+ BufferType = memoryview #XXX: unregistered
63
+ ClassType = type # no 'old-style' classes
64
+ EllipsisType = type(Ellipsis)
65
+ #FileType = IOBase
66
+ NotImplementedType = type(NotImplemented)
67
+ SliceType = slice
68
+ TypeType = type # 'new-style' classes #XXX: unregistered
69
+ XRangeType = range
70
+ from types import MappingProxyType as DictProxyType, new_class
71
+ from pickle import DEFAULT_PROTOCOL, HIGHEST_PROTOCOL, PickleError, PicklingError, UnpicklingError
72
+ import __main__ as _main_module
73
+ import marshal
74
+ import gc
75
+ # import zlib
76
+ import abc
77
+ import dataclasses
78
+ from weakref import ReferenceType, ProxyType, CallableProxyType
79
+ from collections import OrderedDict
80
+ from enum import Enum, EnumMeta
81
+ from functools import partial
82
+ from operator import itemgetter, attrgetter
83
+ GENERATOR_FAIL = False
84
+ import importlib.machinery
85
+ EXTENSION_SUFFIXES = tuple(importlib.machinery.EXTENSION_SUFFIXES)
86
+ try:
87
+ import ctypes
88
+ HAS_CTYPES = True
89
+ # if using `pypy`, pythonapi is not found
90
+ IS_PYPY = not hasattr(ctypes, 'pythonapi')
91
+ except ImportError:
92
+ HAS_CTYPES = False
93
+ IS_PYPY = False
94
+ NumpyUfuncType = None
95
+ NumpyDType = None
96
+ NumpyArrayType = None
97
+ try:
98
+ if not importlib.machinery.PathFinder().find_spec('numpy'):
99
+ raise ImportError("No module named 'numpy'")
100
+ NumpyUfuncType = True
101
+ NumpyDType = True
102
+ NumpyArrayType = True
103
+ except ImportError:
104
+ pass
105
+ def __hook__():
106
+ global NumpyArrayType, NumpyDType, NumpyUfuncType
107
+ from numpy import ufunc as NumpyUfuncType
108
+ from numpy import ndarray as NumpyArrayType
109
+ from numpy import dtype as NumpyDType
110
+ return True
111
+ if NumpyArrayType: # then has numpy
112
+ def ndarraysubclassinstance(obj_type):
113
+ if all((c.__module__, c.__name__) != ('numpy', 'ndarray') for c in obj_type.__mro__):
114
+ return False
115
+ # anything below here is a numpy array (or subclass) instance
116
+ __hook__() # import numpy (so the following works!!!)
117
+ # verify that __reduce__ has not been overridden
118
+ if obj_type.__reduce_ex__ is not NumpyArrayType.__reduce_ex__ \
119
+ or obj_type.__reduce__ is not NumpyArrayType.__reduce__:
120
+ return False
121
+ return True
122
+ def numpyufunc(obj_type):
123
+ return any((c.__module__, c.__name__) == ('numpy', 'ufunc') for c in obj_type.__mro__)
124
+ def numpydtype(obj_type):
125
+ if all((c.__module__, c.__name__) != ('numpy', 'dtype') for c in obj_type.__mro__):
126
+ return False
127
+ # anything below here is a numpy dtype
128
+ __hook__() # import numpy (so the following works!!!)
129
+ return obj_type is type(NumpyDType) # handles subclasses
130
+ else:
131
+ def ndarraysubclassinstance(obj): return False
132
+ def numpyufunc(obj): return False
133
+ def numpydtype(obj): return False
134
+
135
+ from types import GetSetDescriptorType, ClassMethodDescriptorType, \
136
+ WrapperDescriptorType, MethodDescriptorType, MemberDescriptorType, \
137
+ MethodWrapperType #XXX: unused
138
+
139
+ # make sure to add these 'hand-built' types to _typemap
140
+ CellType = type((lambda x: lambda y: x)(0).__closure__[0])
141
+ PartialType = type(partial(int, base=2))
142
+ SuperType = type(super(Exception, TypeError()))
143
+ ItemGetterType = type(itemgetter(0))
144
+ AttrGetterType = type(attrgetter('__repr__'))
145
+
146
+ try:
147
+ from functools import _lru_cache_wrapper as LRUCacheType
148
+ except ImportError:
149
+ LRUCacheType = None
150
+
151
+ if not isinstance(LRUCacheType, type):
152
+ LRUCacheType = None
153
+
154
+ def get_file_type(*args, **kwargs):
155
+ open = kwargs.pop("open", __builtin__.open)
156
+ f = open(os.devnull, *args, **kwargs)
157
+ t = type(f)
158
+ f.close()
159
+ return t
160
+
161
+ IS_PYODIDE = sys.platform == 'emscripten'
162
+
163
+ FileType = get_file_type('rb', buffering=0)
164
+ TextWrapperType = get_file_type('r', buffering=-1)
165
+ BufferedRandomType = None if IS_PYODIDE else get_file_type('r+b', buffering=-1)
166
+ BufferedReaderType = get_file_type('rb', buffering=-1)
167
+ BufferedWriterType = get_file_type('wb', buffering=-1)
168
+ try:
169
+ from _pyio import open as _open
170
+ PyTextWrapperType = get_file_type('r', buffering=-1, open=_open)
171
+ PyBufferedRandomType = None if IS_PYODIDE else get_file_type('r+b', buffering=-1, open=_open)
172
+ PyBufferedReaderType = get_file_type('rb', buffering=-1, open=_open)
173
+ PyBufferedWriterType = get_file_type('wb', buffering=-1, open=_open)
174
+ except ImportError:
175
+ PyTextWrapperType = PyBufferedRandomType = PyBufferedReaderType = PyBufferedWriterType = None
176
+ from io import BytesIO as StringIO
177
+ InputType = OutputType = None
178
+ from socket import socket as SocketType
179
+ #FIXME: additionally calls ForkingPickler.register several times
180
+ from multiprocessing.reduction import _reduce_socket as reduce_socket
181
+ try: #pragma: no cover
182
+ IS_IPYTHON = __IPYTHON__ # is True
183
+ ExitType = None # IPython.core.autocall.ExitAutocall
184
+ IPYTHON_SINGLETONS = ('exit', 'quit', 'get_ipython')
185
+ except NameError:
186
+ IS_IPYTHON = False
187
+ try: ExitType = type(exit) # apparently 'exit' can be removed
188
+ except NameError: ExitType = None
189
+ IPYTHON_SINGLETONS = ()
190
+
191
+ import inspect
192
+ import typing
193
+
194
+
195
+ ### Shims for different versions of Python and dill
196
+ class Sentinel(object):
197
+ """
198
+ Create a unique sentinel object that is pickled as a constant.
199
+ """
200
+ def __init__(self, name, module_name=None):
201
+ self.name = name
202
+ if module_name is None:
203
+ # Use the calling frame's module
204
+ self.__module__ = inspect.currentframe().f_back.f_globals['__name__']
205
+ else:
206
+ self.__module__ = module_name # pragma: no cover
207
+ def __repr__(self):
208
+ return self.__module__ + '.' + self.name # pragma: no cover
209
+ def __copy__(self):
210
+ return self # pragma: no cover
211
+ def __deepcopy__(self, memo):
212
+ return self # pragma: no cover
213
+ def __reduce__(self):
214
+ return self.name
215
+ def __reduce_ex__(self, protocol):
216
+ return self.name
217
+
218
+ from . import _shims
219
+ from ._shims import Reduce, Getattr
220
+
221
+ ### File modes
222
+ #: Pickles the file handle, preserving mode. The position of the unpickled
223
+ #: object is as for a new file handle.
224
+ HANDLE_FMODE = 0
225
+ #: Pickles the file contents, creating a new file if on load the file does
226
+ #: not exist. The position = min(pickled position, EOF) and mode is chosen
227
+ #: as such that "best" preserves behavior of the original file.
228
+ CONTENTS_FMODE = 1
229
+ #: Pickles the entire file (handle and contents), preserving mode and position.
230
+ FILE_FMODE = 2
231
+
232
+ ### Shorthands (modified from python2.5/lib/pickle.py)
233
+ def copy(obj, *args, **kwds):
234
+ """
235
+ Use pickling to 'copy' an object (i.e. `loads(dumps(obj))`).
236
+
237
+ See :func:`dumps` and :func:`loads` for keyword arguments.
238
+ """
239
+ ignore = kwds.pop('ignore', Unpickler.settings['ignore'])
240
+ return loads(dumps(obj, *args, **kwds), ignore=ignore)
241
+
242
+ def dump(obj, file, protocol=None, byref=None, fmode=None, recurse=None, **kwds):#, strictio=None):
243
+ """
244
+ Pickle an object to a file.
245
+
246
+ See :func:`dumps` for keyword arguments.
247
+ """
248
+ from .settings import settings
249
+ protocol = settings['protocol'] if protocol is None else int(protocol)
250
+ _kwds = kwds.copy()
251
+ _kwds.update(dict(byref=byref, fmode=fmode, recurse=recurse))
252
+ Pickler(file, protocol, **_kwds).dump(obj)
253
+ return
254
+
255
+ def dumps(obj, protocol=None, byref=None, fmode=None, recurse=None, **kwds):#, strictio=None):
256
+ """
257
+ Pickle an object to a string.
258
+
259
+ *protocol* is the pickler protocol, as defined for Python *pickle*.
260
+
261
+ If *byref=True*, then dill behaves a lot more like pickle as certain
262
+ objects (like modules) are pickled by reference as opposed to attempting
263
+ to pickle the object itself.
264
+
265
+ If *recurse=True*, then objects referred to in the global dictionary
266
+ are recursively traced and pickled, instead of the default behavior
267
+ of attempting to store the entire global dictionary. This is needed for
268
+ functions defined via *exec()*.
269
+
270
+ *fmode* (:const:`HANDLE_FMODE`, :const:`CONTENTS_FMODE`,
271
+ or :const:`FILE_FMODE`) indicates how file handles will be pickled.
272
+ For example, when pickling a data file handle for transfer to a remote
273
+ compute service, *FILE_FMODE* will include the file contents in the
274
+ pickle and cursor position so that a remote method can operate
275
+ transparently on an object with an open file handle.
276
+
277
+ Default values for keyword arguments can be set in :mod:`dill.settings`.
278
+ """
279
+ file = StringIO()
280
+ dump(obj, file, protocol, byref, fmode, recurse, **kwds)#, strictio)
281
+ return file.getvalue()
282
+
283
+ def load(file, ignore=None, **kwds):
284
+ """
285
+ Unpickle an object from a file.
286
+
287
+ See :func:`loads` for keyword arguments.
288
+ """
289
+ return Unpickler(file, ignore=ignore, **kwds).load()
290
+
291
+ def loads(str, ignore=None, **kwds):
292
+ """
293
+ Unpickle an object from a string.
294
+
295
+ If *ignore=False* then objects whose class is defined in the module
296
+ *__main__* are updated to reference the existing class in *__main__*,
297
+ otherwise they are left to refer to the reconstructed type, which may
298
+ be different.
299
+
300
+ Default values for keyword arguments can be set in :mod:`dill.settings`.
301
+ """
302
+ file = StringIO(str)
303
+ return load(file, ignore, **kwds)
304
+
305
+ # def dumpzs(obj, protocol=None):
306
+ # """pickle an object to a compressed string"""
307
+ # return zlib.compress(dumps(obj, protocol))
308
+
309
+ # def loadzs(str):
310
+ # """unpickle an object from a compressed string"""
311
+ # return loads(zlib.decompress(str))
312
+
313
+ ### End: Shorthands ###
314
+
315
+ class MetaCatchingDict(dict):
316
+ def get(self, key, default=None):
317
+ try:
318
+ return self[key]
319
+ except KeyError:
320
+ return default
321
+
322
+ def __missing__(self, key):
323
+ if issubclass(key, type):
324
+ return save_type
325
+ else:
326
+ raise KeyError()
327
+
328
+ class PickleWarning(Warning, PickleError):
329
+ pass
330
+
331
+ class PicklingWarning(PickleWarning, PicklingError):
332
+ pass
333
+
334
+ class UnpicklingWarning(PickleWarning, UnpicklingError):
335
+ pass
336
+
337
+ ### Extend the Picklers
338
+ class Pickler(StockPickler):
339
+ """python's Pickler extended to interpreter sessions"""
340
+ dispatch: typing.Dict[type, typing.Callable[[Pickler, typing.Any], None]] \
341
+ = MetaCatchingDict(StockPickler.dispatch.copy())
342
+ """The dispatch table, a dictionary of serializing functions used
343
+ by Pickler to save objects of specific types. Use :func:`pickle`
344
+ or :func:`register` to associate types to custom functions.
345
+
346
+ :meta hide-value:
347
+ """
348
+ _session = False
349
+ from .settings import settings
350
+
351
+ def __init__(self, file, *args, **kwds):
352
+ settings = Pickler.settings
353
+ _byref = kwds.pop('byref', None)
354
+ #_strictio = kwds.pop('strictio', None)
355
+ _fmode = kwds.pop('fmode', None)
356
+ _recurse = kwds.pop('recurse', None)
357
+ StockPickler.__init__(self, file, *args, **kwds)
358
+ self._main = _main_module
359
+ self._diff_cache = {}
360
+ self._byref = settings['byref'] if _byref is None else _byref
361
+ self._strictio = False #_strictio
362
+ self._fmode = settings['fmode'] if _fmode is None else _fmode
363
+ self._recurse = settings['recurse'] if _recurse is None else _recurse
364
+ self._postproc = OrderedDict()
365
+ self._file = file
366
+
367
+ def save(self, obj, save_persistent_id=True):
368
+ # numpy hack
369
+ obj_type = type(obj)
370
+ if NumpyArrayType and not (obj_type is type or obj_type in Pickler.dispatch):
371
+ # register if the object is a numpy ufunc
372
+ # thanks to Paul Kienzle for pointing out ufuncs didn't pickle
373
+ if numpyufunc(obj_type):
374
+ @register(obj_type)
375
+ def save_numpy_ufunc(pickler, obj):
376
+ logger.trace(pickler, "Nu: %s", obj)
377
+ name = getattr(obj, '__qualname__', getattr(obj, '__name__', None))
378
+ StockPickler.save_global(pickler, obj, name=name)
379
+ logger.trace(pickler, "# Nu")
380
+ return
381
+ # NOTE: the above 'save' performs like:
382
+ # import copy_reg
383
+ # def udump(f): return f.__name__
384
+ # def uload(name): return getattr(numpy, name)
385
+ # copy_reg.pickle(NumpyUfuncType, udump, uload)
386
+ # register if the object is a numpy dtype
387
+ if numpydtype(obj_type):
388
+ @register(obj_type)
389
+ def save_numpy_dtype(pickler, obj):
390
+ logger.trace(pickler, "Dt: %s", obj)
391
+ pickler.save_reduce(_create_dtypemeta, (obj.type,), obj=obj)
392
+ logger.trace(pickler, "# Dt")
393
+ return
394
+ # NOTE: the above 'save' performs like:
395
+ # import copy_reg
396
+ # def uload(name): return type(NumpyDType(name))
397
+ # def udump(f): return uload, (f.type,)
398
+ # copy_reg.pickle(NumpyDTypeType, udump, uload)
399
+ # register if the object is a subclassed numpy array instance
400
+ if ndarraysubclassinstance(obj_type):
401
+ @register(obj_type)
402
+ def save_numpy_array(pickler, obj):
403
+ logger.trace(pickler, "Nu: (%s, %s)", obj.shape, obj.dtype)
404
+ npdict = getattr(obj, '__dict__', None)
405
+ f, args, state = obj.__reduce__()
406
+ pickler.save_reduce(_create_array, (f,args,state,npdict), obj=obj)
407
+ logger.trace(pickler, "# Nu")
408
+ return
409
+ # end numpy hack
410
+
411
+ if GENERATOR_FAIL and obj_type is GeneratorType:
412
+ msg = "Can't pickle %s: attribute lookup builtins.generator failed" % GeneratorType
413
+ raise PicklingError(msg)
414
+ StockPickler.save(self, obj, save_persistent_id)
415
+
416
+ save.__doc__ = StockPickler.save.__doc__
417
+
418
+ def dump(self, obj): #NOTE: if settings change, need to update attributes
419
+ logger.trace_setup(self)
420
+ StockPickler.dump(self, obj)
421
+ dump.__doc__ = StockPickler.dump.__doc__
422
+
423
+ class Unpickler(StockUnpickler):
424
+ """python's Unpickler extended to interpreter sessions and more types"""
425
+ from .settings import settings
426
+ _session = False
427
+
428
+ def find_class(self, module, name):
429
+ if (module, name) == ('__builtin__', '__main__'):
430
+ return self._main.__dict__ #XXX: above set w/save_module_dict
431
+ elif (module, name) == ('__builtin__', 'NoneType'):
432
+ return type(None) #XXX: special case: NoneType missing
433
+ if module == 'dill.dill': module = 'dill._dill'
434
+ return StockUnpickler.find_class(self, module, name)
435
+
436
+ def __init__(self, *args, **kwds):
437
+ settings = Pickler.settings
438
+ _ignore = kwds.pop('ignore', None)
439
+ StockUnpickler.__init__(self, *args, **kwds)
440
+ self._main = _main_module
441
+ self._ignore = settings['ignore'] if _ignore is None else _ignore
442
+
443
+ def load(self): #NOTE: if settings change, need to update attributes
444
+ obj = StockUnpickler.load(self)
445
+ if type(obj).__module__ == getattr(_main_module, '__name__', '__main__'):
446
+ if not self._ignore:
447
+ # point obj class to main
448
+ try: obj.__class__ = getattr(self._main, type(obj).__name__)
449
+ except (AttributeError,TypeError): pass # defined in a file
450
+ #_main_module.__dict__.update(obj.__dict__) #XXX: should update globals ?
451
+ return obj
452
+ load.__doc__ = StockUnpickler.load.__doc__
453
+ pass
454
+
455
+ '''
456
+ def dispatch_table():
457
+ """get the dispatch table of registered types"""
458
+ return Pickler.dispatch
459
+ '''
460
+
461
+ pickle_dispatch_copy = StockPickler.dispatch.copy()
462
+
463
+ def pickle(t, func):
464
+ """expose :attr:`~Pickler.dispatch` table for user-created extensions"""
465
+ Pickler.dispatch[t] = func
466
+ return
467
+
468
+ def register(t):
469
+ """decorator to register types to Pickler's :attr:`~Pickler.dispatch` table"""
470
+ def proxy(func):
471
+ Pickler.dispatch[t] = func
472
+ return func
473
+ return proxy
474
+
475
+ def _revert_extension():
476
+ """drop dill-registered types from pickle's dispatch table"""
477
+ for type, func in list(StockPickler.dispatch.items()):
478
+ if func.__module__ == __name__:
479
+ del StockPickler.dispatch[type]
480
+ if type in pickle_dispatch_copy:
481
+ StockPickler.dispatch[type] = pickle_dispatch_copy[type]
482
+
483
+ def use_diff(on=True):
484
+ """
485
+ Reduces size of pickles by only including object which have changed.
486
+
487
+ Decreases pickle size but increases CPU time needed.
488
+ Also helps avoid some unpickleable objects.
489
+ MUST be called at start of script, otherwise changes will not be recorded.
490
+ """
491
+ global _use_diff, diff
492
+ _use_diff = on
493
+ if _use_diff and diff is None:
494
+ try:
495
+ from . import diff as d
496
+ except ImportError:
497
+ import diff as d
498
+ diff = d
499
+
500
+ def _create_typemap():
501
+ import types
502
+ d = dict(list(__builtin__.__dict__.items()) + \
503
+ list(types.__dict__.items())).items()
504
+ for key, value in d:
505
+ if getattr(value, '__module__', None) == 'builtins' \
506
+ and type(value) is type:
507
+ yield key, value
508
+ return
509
+ _reverse_typemap = dict(_create_typemap())
510
+ _reverse_typemap.update({
511
+ 'PartialType': PartialType,
512
+ 'SuperType': SuperType,
513
+ 'ItemGetterType': ItemGetterType,
514
+ 'AttrGetterType': AttrGetterType,
515
+ })
516
+ if sys.hexversion < 0x30800a2:
517
+ _reverse_typemap.update({
518
+ 'CellType': CellType,
519
+ })
520
+
521
+ # "Incidental" implementation specific types. Unpickling these types in another
522
+ # implementation of Python (PyPy -> CPython) is not guaranteed to work
523
+
524
+ # This dictionary should contain all types that appear in Python implementations
525
+ # but are not defined in https://docs.python.org/3/library/types.html#standard-interpreter-types
526
+ x=OrderedDict()
527
+ _incedental_reverse_typemap = {
528
+ 'FileType': FileType,
529
+ 'BufferedRandomType': BufferedRandomType,
530
+ 'BufferedReaderType': BufferedReaderType,
531
+ 'BufferedWriterType': BufferedWriterType,
532
+ 'TextWrapperType': TextWrapperType,
533
+ 'PyBufferedRandomType': PyBufferedRandomType,
534
+ 'PyBufferedReaderType': PyBufferedReaderType,
535
+ 'PyBufferedWriterType': PyBufferedWriterType,
536
+ 'PyTextWrapperType': PyTextWrapperType,
537
+ }
538
+
539
+ _incedental_reverse_typemap.update({
540
+ "DictKeysType": type({}.keys()),
541
+ "DictValuesType": type({}.values()),
542
+ "DictItemsType": type({}.items()),
543
+
544
+ "OdictKeysType": type(x.keys()),
545
+ "OdictValuesType": type(x.values()),
546
+ "OdictItemsType": type(x.items()),
547
+ })
548
+
549
+ if ExitType:
550
+ _incedental_reverse_typemap['ExitType'] = ExitType
551
+ if InputType:
552
+ _incedental_reverse_typemap['InputType'] = InputType
553
+ _incedental_reverse_typemap['OutputType'] = OutputType
554
+
555
+ '''
556
+ try:
557
+ import symtable
558
+ _incedental_reverse_typemap["SymtableEntryType"] = type(symtable.symtable("", "string", "exec")._table)
559
+ except: #FIXME: fails to pickle
560
+ pass
561
+
562
+ if sys.hexversion >= 0x30a00a0:
563
+ _incedental_reverse_typemap['LineIteratorType'] = type(compile('3', '', 'eval').co_lines())
564
+ '''
565
+
566
+ if sys.hexversion >= 0x30b00b0:
567
+ from types import GenericAlias
568
+ _incedental_reverse_typemap["GenericAliasIteratorType"] = type(iter(GenericAlias(list, (int,))))
569
+ '''
570
+ _incedental_reverse_typemap['PositionsIteratorType'] = type(compile('3', '', 'eval').co_positions())
571
+ '''
572
+
573
+ try:
574
+ import winreg
575
+ _incedental_reverse_typemap["HKEYType"] = winreg.HKEYType
576
+ except ImportError:
577
+ pass
578
+
579
+ _reverse_typemap.update(_incedental_reverse_typemap)
580
+ _incedental_types = set(_incedental_reverse_typemap.values())
581
+
582
+ del x
583
+
584
+ _typemap = dict((v, k) for k, v in _reverse_typemap.items())
585
+
586
+ def _unmarshal(string):
587
+ return marshal.loads(string)
588
+
589
+ def _load_type(name):
590
+ return _reverse_typemap[name]
591
+
592
+ def _create_type(typeobj, *args):
593
+ return typeobj(*args)
594
+
595
+ def _create_function(fcode, fglobals, fname=None, fdefaults=None,
596
+ fclosure=None, fdict=None, fkwdefaults=None):
597
+ # same as FunctionType, but enable passing __dict__ to new function,
598
+ # __dict__ is the storehouse for attributes added after function creation
599
+ func = FunctionType(fcode, fglobals or dict(), fname, fdefaults, fclosure)
600
+ if fdict is not None:
601
+ func.__dict__.update(fdict) #XXX: better copy? option to copy?
602
+ if fkwdefaults is not None:
603
+ func.__kwdefaults__ = fkwdefaults
604
+ # 'recurse' only stores referenced modules/objects in fglobals,
605
+ # thus we need to make sure that we have __builtins__ as well
606
+ if "__builtins__" not in func.__globals__:
607
+ func.__globals__["__builtins__"] = globals()["__builtins__"]
608
+ # assert id(fglobals) == id(func.__globals__)
609
+ return func
610
+
611
+ class match:
612
+ """
613
+ Make avaialable a limited structural pattern matching-like syntax for Python < 3.10
614
+
615
+ Patterns can be only tuples (without types) currently.
616
+ Inspired by the package pattern-matching-PEP634.
617
+
618
+ Usage:
619
+ >>> with match(args) as m:
620
+ >>> if m.case(('x', 'y')):
621
+ >>> # use m.x and m.y
622
+ >>> elif m.case(('x', 'y', 'z')):
623
+ >>> # use m.x, m.y and m.z
624
+
625
+ Equivalent native code for Python >= 3.10:
626
+ >>> match args:
627
+ >>> case (x, y):
628
+ >>> # use x and y
629
+ >>> case (x, y, z):
630
+ >>> # use x, y and z
631
+ """
632
+ def __init__(self, value):
633
+ self.value = value
634
+ self._fields = None
635
+ def __enter__(self):
636
+ return self
637
+ def __exit__(self, *exc_info):
638
+ return False
639
+ def case(self, args): # *args, **kwargs):
640
+ """just handles tuple patterns"""
641
+ if len(self.value) != len(args): # + len(kwargs):
642
+ return False
643
+ #if not all(isinstance(arg, pat) for arg, pat in zip(self.value[len(args):], kwargs.values())):
644
+ # return False
645
+ self.args = args # (*args, *kwargs)
646
+ return True
647
+ @property
648
+ def fields(self):
649
+ # Only bind names to values if necessary.
650
+ if self._fields is None:
651
+ self._fields = dict(zip(self.args, self.value))
652
+ return self._fields
653
+ def __getattr__(self, item):
654
+ return self.fields[item]
655
+
656
+ ALL_CODE_PARAMS = [
657
+ # Version New attribute CodeType parameters
658
+ ((3,11,'a'), 'co_endlinetable', 'argcount posonlyargcount kwonlyargcount nlocals stacksize flags code consts names varnames filename name qualname firstlineno linetable endlinetable columntable exceptiontable freevars cellvars'),
659
+ ((3,11), 'co_exceptiontable', 'argcount posonlyargcount kwonlyargcount nlocals stacksize flags code consts names varnames filename name qualname firstlineno linetable exceptiontable freevars cellvars'),
660
+ ((3,10), 'co_linetable', 'argcount posonlyargcount kwonlyargcount nlocals stacksize flags code consts names varnames filename name firstlineno linetable freevars cellvars'),
661
+ ((3,8), 'co_posonlyargcount', 'argcount posonlyargcount kwonlyargcount nlocals stacksize flags code consts names varnames filename name firstlineno lnotab freevars cellvars'),
662
+ ((3,7), 'co_kwonlyargcount', 'argcount kwonlyargcount nlocals stacksize flags code consts names varnames filename name firstlineno lnotab freevars cellvars'),
663
+ ]
664
+ for version, new_attr, params in ALL_CODE_PARAMS:
665
+ if hasattr(CodeType, new_attr):
666
+ CODE_VERSION = version
667
+ CODE_PARAMS = params.split()
668
+ break
669
+ ENCODE_PARAMS = set(CODE_PARAMS).intersection(
670
+ ['code', 'lnotab', 'linetable', 'endlinetable', 'columntable', 'exceptiontable'])
671
+
672
+ def _create_code(*args):
673
+ if not isinstance(args[0], int): # co_lnotab stored from >= 3.10
674
+ LNOTAB, *args = args
675
+ else: # from < 3.10 (or pre-LNOTAB storage)
676
+ LNOTAB = b''
677
+
678
+ with match(args) as m:
679
+ # Python 3.11/3.12a (18 members)
680
+ if m.case((
681
+ 'argcount', 'posonlyargcount', 'kwonlyargcount', 'nlocals', 'stacksize', 'flags', # args[0:6]
682
+ 'code', 'consts', 'names', 'varnames', 'filename', 'name', 'qualname', 'firstlineno', # args[6:14]
683
+ 'linetable', 'exceptiontable', 'freevars', 'cellvars' # args[14:]
684
+ )):
685
+ if CODE_VERSION == (3,11):
686
+ return CodeType(
687
+ *args[:6],
688
+ args[6].encode() if hasattr(args[6], 'encode') else args[6], # code
689
+ *args[7:14],
690
+ args[14].encode() if hasattr(args[14], 'encode') else args[14], # linetable
691
+ args[15].encode() if hasattr(args[15], 'encode') else args[15], # exceptiontable
692
+ args[16],
693
+ args[17],
694
+ )
695
+ fields = m.fields
696
+ # Python 3.10 or 3.8/3.9 (16 members)
697
+ elif m.case((
698
+ 'argcount', 'posonlyargcount', 'kwonlyargcount', 'nlocals', 'stacksize', 'flags', # args[0:6]
699
+ 'code', 'consts', 'names', 'varnames', 'filename', 'name', 'firstlineno', # args[6:13]
700
+ 'LNOTAB_OR_LINETABLE', 'freevars', 'cellvars' # args[13:]
701
+ )):
702
+ if CODE_VERSION == (3,10) or CODE_VERSION == (3,8):
703
+ return CodeType(
704
+ *args[:6],
705
+ args[6].encode() if hasattr(args[6], 'encode') else args[6], # code
706
+ *args[7:13],
707
+ args[13].encode() if hasattr(args[13], 'encode') else args[13], # lnotab/linetable
708
+ args[14],
709
+ args[15],
710
+ )
711
+ fields = m.fields
712
+ if CODE_VERSION >= (3,10):
713
+ fields['linetable'] = m.LNOTAB_OR_LINETABLE
714
+ else:
715
+ fields['lnotab'] = LNOTAB if LNOTAB else m.LNOTAB_OR_LINETABLE
716
+ # Python 3.7 (15 args)
717
+ elif m.case((
718
+ 'argcount', 'kwonlyargcount', 'nlocals', 'stacksize', 'flags', # args[0:5]
719
+ 'code', 'consts', 'names', 'varnames', 'filename', 'name', 'firstlineno', # args[5:12]
720
+ 'lnotab', 'freevars', 'cellvars' # args[12:]
721
+ )):
722
+ if CODE_VERSION == (3,7):
723
+ return CodeType(
724
+ *args[:5],
725
+ args[5].encode() if hasattr(args[5], 'encode') else args[5], # code
726
+ *args[6:12],
727
+ args[12].encode() if hasattr(args[12], 'encode') else args[12], # lnotab
728
+ args[13],
729
+ args[14],
730
+ )
731
+ fields = m.fields
732
+ # Python 3.11a (20 members)
733
+ elif m.case((
734
+ 'argcount', 'posonlyargcount', 'kwonlyargcount', 'nlocals', 'stacksize', 'flags', # args[0:6]
735
+ 'code', 'consts', 'names', 'varnames', 'filename', 'name', 'qualname', 'firstlineno', # args[6:14]
736
+ 'linetable', 'endlinetable', 'columntable', 'exceptiontable', 'freevars', 'cellvars' # args[14:]
737
+ )):
738
+ if CODE_VERSION == (3,11,'a'):
739
+ return CodeType(
740
+ *args[:6],
741
+ args[6].encode() if hasattr(args[6], 'encode') else args[6], # code
742
+ *args[7:14],
743
+ *(a.encode() if hasattr(a, 'encode') else a for a in args[14:18]), # linetable-exceptiontable
744
+ args[18],
745
+ args[19],
746
+ )
747
+ fields = m.fields
748
+ else:
749
+ raise UnpicklingError("pattern match for code object failed")
750
+
751
+ # The args format doesn't match this version.
752
+ fields.setdefault('posonlyargcount', 0) # from python <= 3.7
753
+ fields.setdefault('lnotab', LNOTAB) # from python >= 3.10
754
+ fields.setdefault('linetable', b'') # from python <= 3.9
755
+ fields.setdefault('qualname', fields['name']) # from python <= 3.10
756
+ fields.setdefault('exceptiontable', b'') # from python <= 3.10
757
+ fields.setdefault('endlinetable', None) # from python != 3.11a
758
+ fields.setdefault('columntable', None) # from python != 3.11a
759
+
760
+ args = (fields[k].encode() if k in ENCODE_PARAMS and hasattr(fields[k], 'encode') else fields[k]
761
+ for k in CODE_PARAMS)
762
+ return CodeType(*args)
763
+
764
+ def _create_ftype(ftypeobj, func, args, kwds):
765
+ if kwds is None:
766
+ kwds = {}
767
+ if args is None:
768
+ args = ()
769
+ return ftypeobj(func, *args, **kwds)
770
+
771
+ def _create_typing_tuple(argz, *args): #NOTE: workaround python/cpython#94245
772
+ if not argz:
773
+ return typing.Tuple[()].copy_with(())
774
+ if argz == ((),):
775
+ return typing.Tuple[()]
776
+ return typing.Tuple[argz]
777
+
778
+ def _create_lock(locked, *args): #XXX: ignores 'blocking'
779
+ from threading import Lock
780
+ lock = Lock()
781
+ if locked:
782
+ if not lock.acquire(False):
783
+ raise UnpicklingError("Cannot acquire lock")
784
+ return lock
785
+
786
+ def _create_rlock(count, owner, *args): #XXX: ignores 'blocking'
787
+ lock = RLockType()
788
+ if owner is not None:
789
+ lock._acquire_restore((count, owner))
790
+ if owner and not lock._is_owned():
791
+ raise UnpicklingError("Cannot acquire lock")
792
+ return lock
793
+
794
+ # thanks to matsjoyce for adding all the different file modes
795
+ def _create_filehandle(name, mode, position, closed, open, strictio, fmode, fdata): # buffering=0
796
+ # only pickles the handle, not the file contents... good? or StringIO(data)?
797
+ # (for file contents see: http://effbot.org/librarybook/copy-reg.htm)
798
+ # NOTE: handle special cases first (are there more special cases?)
799
+ names = {'<stdin>':sys.__stdin__, '<stdout>':sys.__stdout__,
800
+ '<stderr>':sys.__stderr__} #XXX: better fileno=(0,1,2) ?
801
+ if name in list(names.keys()):
802
+ f = names[name] #XXX: safer "f=sys.stdin"
803
+ elif name == '<tmpfile>':
804
+ f = os.tmpfile()
805
+ elif name == '<fdopen>':
806
+ import tempfile
807
+ f = tempfile.TemporaryFile(mode)
808
+ else:
809
+ try:
810
+ exists = os.path.exists(name)
811
+ except Exception:
812
+ exists = False
813
+ if not exists:
814
+ if strictio:
815
+ raise FileNotFoundError("[Errno 2] No such file or directory: '%s'" % name)
816
+ elif "r" in mode and fmode != FILE_FMODE:
817
+ name = '<fdopen>' # or os.devnull?
818
+ current_size = 0 # or maintain position?
819
+ else:
820
+ current_size = os.path.getsize(name)
821
+
822
+ if position > current_size:
823
+ if strictio:
824
+ raise ValueError("invalid buffer size")
825
+ elif fmode == CONTENTS_FMODE:
826
+ position = current_size
827
+ # try to open the file by name
828
+ # NOTE: has different fileno
829
+ try:
830
+ #FIXME: missing: *buffering*, encoding, softspace
831
+ if fmode == FILE_FMODE:
832
+ f = open(name, mode if "w" in mode else "w")
833
+ f.write(fdata)
834
+ if "w" not in mode:
835
+ f.close()
836
+ f = open(name, mode)
837
+ elif name == '<fdopen>': # file did not exist
838
+ import tempfile
839
+ f = tempfile.TemporaryFile(mode)
840
+ # treat x mode as w mode
841
+ elif fmode == CONTENTS_FMODE \
842
+ and ("w" in mode or "x" in mode):
843
+ # stop truncation when opening
844
+ flags = os.O_CREAT
845
+ if "+" in mode:
846
+ flags |= os.O_RDWR
847
+ else:
848
+ flags |= os.O_WRONLY
849
+ f = os.fdopen(os.open(name, flags), mode)
850
+ # set name to the correct value
851
+ r = getattr(f, "buffer", f)
852
+ r = getattr(r, "raw", r)
853
+ r.name = name
854
+ assert f.name == name
855
+ else:
856
+ f = open(name, mode)
857
+ except (IOError, FileNotFoundError):
858
+ err = sys.exc_info()[1]
859
+ raise UnpicklingError(err)
860
+ if closed:
861
+ f.close()
862
+ elif position >= 0 and fmode != HANDLE_FMODE:
863
+ f.seek(position)
864
+ return f
865
+
866
+ def _create_stringi(value, position, closed):
867
+ f = StringIO(value)
868
+ if closed: f.close()
869
+ else: f.seek(position)
870
+ return f
871
+
872
+ def _create_stringo(value, position, closed):
873
+ f = StringIO()
874
+ if closed: f.close()
875
+ else:
876
+ f.write(value)
877
+ f.seek(position)
878
+ return f
879
+
880
+ class _itemgetter_helper(object):
881
+ def __init__(self):
882
+ self.items = []
883
+ def __getitem__(self, item):
884
+ self.items.append(item)
885
+ return
886
+
887
+ class _attrgetter_helper(object):
888
+ def __init__(self, attrs, index=None):
889
+ self.attrs = attrs
890
+ self.index = index
891
+ def __getattribute__(self, attr):
892
+ attrs = object.__getattribute__(self, "attrs")
893
+ index = object.__getattribute__(self, "index")
894
+ if index is None:
895
+ index = len(attrs)
896
+ attrs.append(attr)
897
+ else:
898
+ attrs[index] = ".".join([attrs[index], attr])
899
+ return type(self)(attrs, index)
900
+
901
+ class _dictproxy_helper(dict):
902
+ def __ror__(self, a):
903
+ return a
904
+
905
+ _dictproxy_helper_instance = _dictproxy_helper()
906
+
907
+ __d = {}
908
+ try:
909
+ # In CPython 3.9 and later, this trick can be used to exploit the
910
+ # implementation of the __or__ function of MappingProxyType to get the true
911
+ # mapping referenced by the proxy. It may work for other implementations,
912
+ # but is not guaranteed.
913
+ MAPPING_PROXY_TRICK = __d is (DictProxyType(__d) | _dictproxy_helper_instance)
914
+ except Exception:
915
+ MAPPING_PROXY_TRICK = False
916
+ del __d
917
+
918
+ # _CELL_REF and _CELL_EMPTY are used to stay compatible with versions of dill
919
+ # whose _create_cell functions do not have a default value.
920
+ # _CELL_REF can be safely removed entirely (replaced by empty tuples for calls
921
+ # to _create_cell) once breaking changes are allowed.
922
+ _CELL_REF = None
923
+ _CELL_EMPTY = Sentinel('_CELL_EMPTY')
924
+
925
+ def _create_cell(contents=None):
926
+ if contents is not _CELL_EMPTY:
927
+ value = contents
928
+ return (lambda: value).__closure__[0]
929
+
930
+ def _create_weakref(obj, *args):
931
+ from weakref import ref
932
+ if obj is None: # it's dead
933
+ from collections import UserDict
934
+ return ref(UserDict(), *args)
935
+ return ref(obj, *args)
936
+
937
+ def _create_weakproxy(obj, callable=False, *args):
938
+ from weakref import proxy
939
+ if obj is None: # it's dead
940
+ if callable: return proxy(lambda x:x, *args)
941
+ from collections import UserDict
942
+ return proxy(UserDict(), *args)
943
+ return proxy(obj, *args)
944
+
945
+ def _eval_repr(repr_str):
946
+ return eval(repr_str)
947
+
948
+ def _create_array(f, args, state, npdict=None):
949
+ #array = numpy.core.multiarray._reconstruct(*args)
950
+ array = f(*args)
951
+ array.__setstate__(state)
952
+ if npdict is not None: # we also have saved state in __dict__
953
+ array.__dict__.update(npdict)
954
+ return array
955
+
956
+ def _create_dtypemeta(scalar_type):
957
+ if NumpyDType is True: __hook__() # a bit hacky I think
958
+ if scalar_type is None:
959
+ return NumpyDType
960
+ return type(NumpyDType(scalar_type))
961
+
962
+ def _create_namedtuple(name, fieldnames, modulename, defaults=None):
963
+ class_ = _import_module(modulename + '.' + name, safe=True)
964
+ if class_ is not None:
965
+ return class_
966
+ import collections
967
+ t = collections.namedtuple(name, fieldnames, defaults=defaults, module=modulename)
968
+ return t
969
+
970
+ def _create_capsule(pointer, name, context, destructor):
971
+ attr_found = False
972
+ try:
973
+ # based on https://github.com/python/cpython/blob/f4095e53ab708d95e019c909d5928502775ba68f/Objects/capsule.c#L209-L231
974
+ uname = name.decode('utf8')
975
+ for i in range(1, uname.count('.')+1):
976
+ names = uname.rsplit('.', i)
977
+ try:
978
+ module = __import__(names[0])
979
+ except ImportError:
980
+ pass
981
+ obj = module
982
+ for attr in names[1:]:
983
+ obj = getattr(obj, attr)
984
+ capsule = obj
985
+ attr_found = True
986
+ break
987
+ except Exception:
988
+ pass
989
+
990
+ if attr_found:
991
+ if _PyCapsule_IsValid(capsule, name):
992
+ return capsule
993
+ raise UnpicklingError("%s object exists at %s but a PyCapsule object was expected." % (type(capsule), name))
994
+ else:
995
+ #warnings.warn('Creating a new PyCapsule %s for a C data structure that may not be present in memory. Segmentation faults or other memory errors are possible.' % (name,), UnpicklingWarning)
996
+ capsule = _PyCapsule_New(pointer, name, destructor)
997
+ _PyCapsule_SetContext(capsule, context)
998
+ return capsule
999
+
1000
+ def _getattr(objclass, name, repr_str):
1001
+ # hack to grab the reference directly
1002
+ try: #XXX: works only for __builtin__ ?
1003
+ attr = repr_str.split("'")[3]
1004
+ return eval(attr+'.__dict__["'+name+'"]')
1005
+ except Exception:
1006
+ try:
1007
+ attr = objclass.__dict__
1008
+ if type(attr) is DictProxyType:
1009
+ attr = attr[name]
1010
+ else:
1011
+ attr = getattr(objclass,name)
1012
+ except (AttributeError, KeyError):
1013
+ attr = getattr(objclass,name)
1014
+ return attr
1015
+
1016
+ def _get_attr(self, name):
1017
+ # stop recursive pickling
1018
+ return getattr(self, name, None) or getattr(__builtin__, name)
1019
+
1020
+ def _import_module(import_name, safe=False):
1021
+ try:
1022
+ if import_name.startswith('__runtime__.'):
1023
+ return sys.modules[import_name]
1024
+ elif '.' in import_name:
1025
+ items = import_name.split('.')
1026
+ module = '.'.join(items[:-1])
1027
+ obj = items[-1]
1028
+ submodule = getattr(__import__(module, None, None, [obj]), obj)
1029
+ if isinstance(submodule, (ModuleType, type)):
1030
+ return submodule
1031
+ return __import__(import_name, None, None, [obj])
1032
+ else:
1033
+ return __import__(import_name)
1034
+ except (ImportError, AttributeError, KeyError):
1035
+ if safe:
1036
+ return None
1037
+ raise
1038
+
1039
+ # https://github.com/python/cpython/blob/a8912a0f8d9eba6d502c37d522221f9933e976db/Lib/pickle.py#L322-L333
1040
+ def _getattribute(obj, name):
1041
+ for subpath in name.split('.'):
1042
+ if subpath == '<locals>':
1043
+ raise AttributeError("Can't get local attribute {!r} on {!r}"
1044
+ .format(name, obj))
1045
+ try:
1046
+ parent = obj
1047
+ obj = getattr(obj, subpath)
1048
+ except AttributeError:
1049
+ raise AttributeError("Can't get attribute {!r} on {!r}"
1050
+ .format(name, obj))
1051
+ return obj, parent
1052
+
1053
+ def _locate_function(obj, pickler=None):
1054
+ module_name = getattr(obj, '__module__', None)
1055
+ if module_name in ['__main__', None] or \
1056
+ pickler and is_dill(pickler, child=False) and pickler._session and module_name == pickler._main.__name__:
1057
+ return False
1058
+ if hasattr(obj, '__qualname__'):
1059
+ module = _import_module(module_name, safe=True)
1060
+ try:
1061
+ found, _ = _getattribute(module, obj.__qualname__)
1062
+ return found is obj
1063
+ except AttributeError:
1064
+ return False
1065
+ else:
1066
+ found = _import_module(module_name + '.' + obj.__name__, safe=True)
1067
+ return found is obj
1068
+
1069
+
1070
+ def _setitems(dest, source):
1071
+ for k, v in source.items():
1072
+ dest[k] = v
1073
+
1074
+
1075
+ def _save_with_postproc(pickler, reduction, is_pickler_dill=None, obj=Getattr.NO_DEFAULT, postproc_list=None):
1076
+ if obj is Getattr.NO_DEFAULT:
1077
+ obj = Reduce(reduction) # pragma: no cover
1078
+
1079
+ if is_pickler_dill is None:
1080
+ is_pickler_dill = is_dill(pickler, child=True)
1081
+ if is_pickler_dill:
1082
+ # assert id(obj) not in pickler._postproc, str(obj) + ' already pushed on stack!'
1083
+ # if not hasattr(pickler, 'x'): pickler.x = 0
1084
+ # print(pickler.x*' ', 'push', obj, id(obj), pickler._recurse)
1085
+ # pickler.x += 1
1086
+ if postproc_list is None:
1087
+ postproc_list = []
1088
+
1089
+ # Recursive object not supported. Default to a global instead.
1090
+ if id(obj) in pickler._postproc:
1091
+ name = '%s.%s ' % (obj.__module__, getattr(obj, '__qualname__', obj.__name__)) if hasattr(obj, '__module__') else ''
1092
+ warnings.warn('Cannot pickle %r: %shas recursive self-references that trigger a RecursionError.' % (obj, name), PicklingWarning)
1093
+ pickler.save_global(obj)
1094
+ return
1095
+ pickler._postproc[id(obj)] = postproc_list
1096
+
1097
+ # TODO: Use state_setter in Python 3.8 to allow for faster cPickle implementations
1098
+ pickler.save_reduce(*reduction, obj=obj)
1099
+
1100
+ if is_pickler_dill:
1101
+ # pickler.x -= 1
1102
+ # print(pickler.x*' ', 'pop', obj, id(obj))
1103
+ postproc = pickler._postproc.pop(id(obj))
1104
+ # assert postproc_list == postproc, 'Stack tampered!'
1105
+ for reduction in reversed(postproc):
1106
+ if reduction[0] is _setitems:
1107
+ # use the internal machinery of pickle.py to speedup when
1108
+ # updating a dictionary in postproc
1109
+ dest, source = reduction[1]
1110
+ if source:
1111
+ pickler.write(pickler.get(pickler.memo[id(dest)][0]))
1112
+ pickler._batch_setitems(iter(source.items()))
1113
+ else:
1114
+ # Updating with an empty dictionary. Same as doing nothing.
1115
+ continue
1116
+ else:
1117
+ pickler.save_reduce(*reduction)
1118
+ # pop None created by calling preprocessing step off stack
1119
+ pickler.write(POP)
1120
+
1121
+ #@register(CodeType)
1122
+ #def save_code(pickler, obj):
1123
+ # logger.trace(pickler, "Co: %s", obj)
1124
+ # pickler.save_reduce(_unmarshal, (marshal.dumps(obj),), obj=obj)
1125
+ # logger.trace(pickler, "# Co")
1126
+ # return
1127
+
1128
+ # The following function is based on 'save_codeobject' from 'cloudpickle'
1129
+ # Copyright (c) 2012, Regents of the University of California.
1130
+ # Copyright (c) 2009 `PiCloud, Inc. <http://www.picloud.com>`_.
1131
+ # License: https://github.com/cloudpipe/cloudpickle/blob/master/LICENSE
1132
+ @register(CodeType)
1133
+ def save_code(pickler, obj):
1134
+ logger.trace(pickler, "Co: %s", obj)
1135
+ if hasattr(obj, "co_endlinetable"): # python 3.11a (20 args)
1136
+ args = (
1137
+ obj.co_lnotab, # for < python 3.10 [not counted in args]
1138
+ obj.co_argcount, obj.co_posonlyargcount,
1139
+ obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
1140
+ obj.co_flags, obj.co_code, obj.co_consts, obj.co_names,
1141
+ obj.co_varnames, obj.co_filename, obj.co_name, obj.co_qualname,
1142
+ obj.co_firstlineno, obj.co_linetable, obj.co_endlinetable,
1143
+ obj.co_columntable, obj.co_exceptiontable, obj.co_freevars,
1144
+ obj.co_cellvars
1145
+ )
1146
+ elif hasattr(obj, "co_exceptiontable"): # python 3.11 (18 args)
1147
+ with warnings.catch_warnings():
1148
+ if not OLD312a7: # issue 597
1149
+ warnings.filterwarnings('ignore', category=DeprecationWarning)
1150
+ args = (
1151
+ obj.co_lnotab, # for < python 3.10 [not counted in args]
1152
+ obj.co_argcount, obj.co_posonlyargcount,
1153
+ obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
1154
+ obj.co_flags, obj.co_code, obj.co_consts, obj.co_names,
1155
+ obj.co_varnames, obj.co_filename, obj.co_name, obj.co_qualname,
1156
+ obj.co_firstlineno, obj.co_linetable, obj.co_exceptiontable,
1157
+ obj.co_freevars, obj.co_cellvars
1158
+ )
1159
+ elif hasattr(obj, "co_linetable"): # python 3.10 (16 args)
1160
+ args = (
1161
+ obj.co_lnotab, # for < python 3.10 [not counted in args]
1162
+ obj.co_argcount, obj.co_posonlyargcount,
1163
+ obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
1164
+ obj.co_flags, obj.co_code, obj.co_consts, obj.co_names,
1165
+ obj.co_varnames, obj.co_filename, obj.co_name,
1166
+ obj.co_firstlineno, obj.co_linetable, obj.co_freevars,
1167
+ obj.co_cellvars
1168
+ )
1169
+ elif hasattr(obj, "co_posonlyargcount"): # python 3.8 (16 args)
1170
+ args = (
1171
+ obj.co_argcount, obj.co_posonlyargcount,
1172
+ obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
1173
+ obj.co_flags, obj.co_code, obj.co_consts, obj.co_names,
1174
+ obj.co_varnames, obj.co_filename, obj.co_name,
1175
+ obj.co_firstlineno, obj.co_lnotab, obj.co_freevars,
1176
+ obj.co_cellvars
1177
+ )
1178
+ else: # python 3.7 (15 args)
1179
+ args = (
1180
+ obj.co_argcount, obj.co_kwonlyargcount, obj.co_nlocals,
1181
+ obj.co_stacksize, obj.co_flags, obj.co_code, obj.co_consts,
1182
+ obj.co_names, obj.co_varnames, obj.co_filename,
1183
+ obj.co_name, obj.co_firstlineno, obj.co_lnotab,
1184
+ obj.co_freevars, obj.co_cellvars
1185
+ )
1186
+
1187
+ pickler.save_reduce(_create_code, args, obj=obj)
1188
+ logger.trace(pickler, "# Co")
1189
+ return
1190
+
1191
+ def _repr_dict(obj):
1192
+ """Make a short string representation of a dictionary."""
1193
+ return "<%s object at %#012x>" % (type(obj).__name__, id(obj))
1194
+
1195
+ @register(dict)
1196
+ def save_module_dict(pickler, obj):
1197
+ if is_dill(pickler, child=False) and obj == pickler._main.__dict__ and \
1198
+ not (pickler._session and pickler._first_pass):
1199
+ logger.trace(pickler, "D1: %s", _repr_dict(obj)) # obj
1200
+ pickler.write(bytes('c__builtin__\n__main__\n', 'UTF-8'))
1201
+ logger.trace(pickler, "# D1")
1202
+ elif (not is_dill(pickler, child=False)) and (obj == _main_module.__dict__):
1203
+ logger.trace(pickler, "D3: %s", _repr_dict(obj)) # obj
1204
+ pickler.write(bytes('c__main__\n__dict__\n', 'UTF-8')) #XXX: works in general?
1205
+ logger.trace(pickler, "# D3")
1206
+ elif '__name__' in obj and obj != _main_module.__dict__ \
1207
+ and type(obj['__name__']) is str \
1208
+ and obj is getattr(_import_module(obj['__name__'],True), '__dict__', None):
1209
+ logger.trace(pickler, "D4: %s", _repr_dict(obj)) # obj
1210
+ pickler.write(bytes('c%s\n__dict__\n' % obj['__name__'], 'UTF-8'))
1211
+ logger.trace(pickler, "# D4")
1212
+ else:
1213
+ logger.trace(pickler, "D2: %s", _repr_dict(obj)) # obj
1214
+ if is_dill(pickler, child=False) and pickler._session:
1215
+ # we only care about session the first pass thru
1216
+ pickler._first_pass = False
1217
+ StockPickler.save_dict(pickler, obj)
1218
+ logger.trace(pickler, "# D2")
1219
+ return
1220
+
1221
+
1222
+ if not OLD310 and MAPPING_PROXY_TRICK:
1223
+ def save_dict_view(dicttype):
1224
+ def save_dict_view_for_function(func):
1225
+ def _save_dict_view(pickler, obj):
1226
+ logger.trace(pickler, "Dkvi: <%s>", obj)
1227
+ mapping = obj.mapping | _dictproxy_helper_instance
1228
+ pickler.save_reduce(func, (mapping,), obj=obj)
1229
+ logger.trace(pickler, "# Dkvi")
1230
+ return _save_dict_view
1231
+ return [
1232
+ (funcname, save_dict_view_for_function(getattr(dicttype, funcname)))
1233
+ for funcname in ('keys', 'values', 'items')
1234
+ ]
1235
+ else:
1236
+ # The following functions are based on 'cloudpickle'
1237
+ # https://github.com/cloudpipe/cloudpickle/blob/5d89947288a18029672596a4d719093cc6d5a412/cloudpickle/cloudpickle.py#L922-L940
1238
+ # Copyright (c) 2012, Regents of the University of California.
1239
+ # Copyright (c) 2009 `PiCloud, Inc. <http://www.picloud.com>`_.
1240
+ # License: https://github.com/cloudpipe/cloudpickle/blob/master/LICENSE
1241
+ def save_dict_view(dicttype):
1242
+ def save_dict_keys(pickler, obj):
1243
+ logger.trace(pickler, "Dk: <%s>", obj)
1244
+ dict_constructor = _shims.Reduce(dicttype.fromkeys, (list(obj),))
1245
+ pickler.save_reduce(dicttype.keys, (dict_constructor,), obj=obj)
1246
+ logger.trace(pickler, "# Dk")
1247
+
1248
+ def save_dict_values(pickler, obj):
1249
+ logger.trace(pickler, "Dv: <%s>", obj)
1250
+ dict_constructor = _shims.Reduce(dicttype, (enumerate(obj),))
1251
+ pickler.save_reduce(dicttype.values, (dict_constructor,), obj=obj)
1252
+ logger.trace(pickler, "# Dv")
1253
+
1254
+ def save_dict_items(pickler, obj):
1255
+ logger.trace(pickler, "Di: <%s>", obj)
1256
+ pickler.save_reduce(dicttype.items, (dicttype(obj),), obj=obj)
1257
+ logger.trace(pickler, "# Di")
1258
+
1259
+ return (
1260
+ ('keys', save_dict_keys),
1261
+ ('values', save_dict_values),
1262
+ ('items', save_dict_items)
1263
+ )
1264
+
1265
+ for __dicttype in (
1266
+ dict,
1267
+ OrderedDict
1268
+ ):
1269
+ __obj = __dicttype()
1270
+ for __funcname, __savefunc in save_dict_view(__dicttype):
1271
+ __tview = type(getattr(__obj, __funcname)())
1272
+ if __tview not in Pickler.dispatch:
1273
+ Pickler.dispatch[__tview] = __savefunc
1274
+ del __dicttype, __obj, __funcname, __tview, __savefunc
1275
+
1276
+
1277
+ @register(ClassType)
1278
+ def save_classobj(pickler, obj): #FIXME: enable pickler._byref
1279
+ if not _locate_function(obj, pickler):
1280
+ logger.trace(pickler, "C1: %s", obj)
1281
+ pickler.save_reduce(ClassType, (obj.__name__, obj.__bases__,
1282
+ obj.__dict__), obj=obj)
1283
+ #XXX: or obj.__dict__.copy()), obj=obj) ?
1284
+ logger.trace(pickler, "# C1")
1285
+ else:
1286
+ logger.trace(pickler, "C2: %s", obj)
1287
+ name = getattr(obj, '__qualname__', getattr(obj, '__name__', None))
1288
+ StockPickler.save_global(pickler, obj, name=name)
1289
+ logger.trace(pickler, "# C2")
1290
+ return
1291
+
1292
+ @register(typing._GenericAlias)
1293
+ def save_generic_alias(pickler, obj):
1294
+ args = obj.__args__
1295
+ if type(obj.__reduce__()) is str:
1296
+ logger.trace(pickler, "Ga0: %s", obj)
1297
+ StockPickler.save_global(pickler, obj, name=obj.__reduce__())
1298
+ logger.trace(pickler, "# Ga0")
1299
+ elif obj.__origin__ is tuple and (not args or args == ((),)):
1300
+ logger.trace(pickler, "Ga1: %s", obj)
1301
+ pickler.save_reduce(_create_typing_tuple, (args,), obj=obj)
1302
+ logger.trace(pickler, "# Ga1")
1303
+ else:
1304
+ logger.trace(pickler, "Ga2: %s", obj)
1305
+ StockPickler.save_reduce(pickler, *obj.__reduce__(), obj=obj)
1306
+ logger.trace(pickler, "# Ga2")
1307
+ return
1308
+
1309
+ @register(LockType)
1310
+ def save_lock(pickler, obj):
1311
+ logger.trace(pickler, "Lo: %s", obj)
1312
+ pickler.save_reduce(_create_lock, (obj.locked(),), obj=obj)
1313
+ logger.trace(pickler, "# Lo")
1314
+ return
1315
+
1316
+ @register(RLockType)
1317
+ def save_rlock(pickler, obj):
1318
+ logger.trace(pickler, "RL: %s", obj)
1319
+ r = obj.__repr__() # don't use _release_save as it unlocks the lock
1320
+ count = int(r.split('count=')[1].split()[0].rstrip('>'))
1321
+ owner = int(r.split('owner=')[1].split()[0])
1322
+ pickler.save_reduce(_create_rlock, (count,owner,), obj=obj)
1323
+ logger.trace(pickler, "# RL")
1324
+ return
1325
+
1326
+ #@register(SocketType) #FIXME: causes multiprocess test_pickling FAIL
1327
+ def save_socket(pickler, obj):
1328
+ logger.trace(pickler, "So: %s", obj)
1329
+ pickler.save_reduce(*reduce_socket(obj))
1330
+ logger.trace(pickler, "# So")
1331
+ return
1332
+
1333
+ def _save_file(pickler, obj, open_):
1334
+ if obj.closed:
1335
+ position = 0
1336
+ else:
1337
+ obj.flush()
1338
+ if obj in (sys.__stdout__, sys.__stderr__, sys.__stdin__):
1339
+ position = -1
1340
+ else:
1341
+ position = obj.tell()
1342
+ if is_dill(pickler, child=True) and pickler._fmode == FILE_FMODE:
1343
+ f = open_(obj.name, "r")
1344
+ fdata = f.read()
1345
+ f.close()
1346
+ else:
1347
+ fdata = ""
1348
+ if is_dill(pickler, child=True):
1349
+ strictio = pickler._strictio
1350
+ fmode = pickler._fmode
1351
+ else:
1352
+ strictio = False
1353
+ fmode = 0 # HANDLE_FMODE
1354
+ pickler.save_reduce(_create_filehandle, (obj.name, obj.mode, position,
1355
+ obj.closed, open_, strictio,
1356
+ fmode, fdata), obj=obj)
1357
+ return
1358
+
1359
+
1360
+ @register(FileType) #XXX: in 3.x has buffer=0, needs different _create?
1361
+ @register(BufferedReaderType)
1362
+ @register(BufferedWriterType)
1363
+ @register(TextWrapperType)
1364
+ def save_file(pickler, obj):
1365
+ logger.trace(pickler, "Fi: %s", obj)
1366
+ f = _save_file(pickler, obj, open)
1367
+ logger.trace(pickler, "# Fi")
1368
+ return f
1369
+
1370
+ if BufferedRandomType:
1371
+ @register(BufferedRandomType)
1372
+ def save_file(pickler, obj):
1373
+ logger.trace(pickler, "Fi: %s", obj)
1374
+ f = _save_file(pickler, obj, open)
1375
+ logger.trace(pickler, "# Fi")
1376
+ return f
1377
+
1378
+ if PyTextWrapperType:
1379
+ @register(PyBufferedReaderType)
1380
+ @register(PyBufferedWriterType)
1381
+ @register(PyTextWrapperType)
1382
+ def save_file(pickler, obj):
1383
+ logger.trace(pickler, "Fi: %s", obj)
1384
+ f = _save_file(pickler, obj, _open)
1385
+ logger.trace(pickler, "# Fi")
1386
+ return f
1387
+
1388
+ if PyBufferedRandomType:
1389
+ @register(PyBufferedRandomType)
1390
+ def save_file(pickler, obj):
1391
+ logger.trace(pickler, "Fi: %s", obj)
1392
+ f = _save_file(pickler, obj, _open)
1393
+ logger.trace(pickler, "# Fi")
1394
+ return f
1395
+
1396
+
1397
+ # The following two functions are based on 'saveCStringIoInput'
1398
+ # and 'saveCStringIoOutput' from spickle
1399
+ # Copyright (c) 2011 by science+computing ag
1400
+ # License: http://www.apache.org/licenses/LICENSE-2.0
1401
+ if InputType:
1402
+ @register(InputType)
1403
+ def save_stringi(pickler, obj):
1404
+ logger.trace(pickler, "Io: %s", obj)
1405
+ if obj.closed:
1406
+ value = ''; position = 0
1407
+ else:
1408
+ value = obj.getvalue(); position = obj.tell()
1409
+ pickler.save_reduce(_create_stringi, (value, position, \
1410
+ obj.closed), obj=obj)
1411
+ logger.trace(pickler, "# Io")
1412
+ return
1413
+
1414
+ @register(OutputType)
1415
+ def save_stringo(pickler, obj):
1416
+ logger.trace(pickler, "Io: %s", obj)
1417
+ if obj.closed:
1418
+ value = ''; position = 0
1419
+ else:
1420
+ value = obj.getvalue(); position = obj.tell()
1421
+ pickler.save_reduce(_create_stringo, (value, position, \
1422
+ obj.closed), obj=obj)
1423
+ logger.trace(pickler, "# Io")
1424
+ return
1425
+
1426
+ if LRUCacheType is not None:
1427
+ from functools import lru_cache
1428
+ @register(LRUCacheType)
1429
+ def save_lru_cache(pickler, obj):
1430
+ logger.trace(pickler, "LRU: %s", obj)
1431
+ if OLD39:
1432
+ kwargs = obj.cache_info()
1433
+ args = (kwargs.maxsize,)
1434
+ else:
1435
+ kwargs = obj.cache_parameters()
1436
+ args = (kwargs['maxsize'], kwargs['typed'])
1437
+ if args != lru_cache.__defaults__:
1438
+ wrapper = Reduce(lru_cache, args, is_callable=True)
1439
+ else:
1440
+ wrapper = lru_cache
1441
+ pickler.save_reduce(wrapper, (obj.__wrapped__,), obj=obj)
1442
+ logger.trace(pickler, "# LRU")
1443
+ return
1444
+
1445
+ @register(SuperType)
1446
+ def save_super(pickler, obj):
1447
+ logger.trace(pickler, "Su: %s", obj)
1448
+ pickler.save_reduce(super, (obj.__thisclass__, obj.__self__), obj=obj)
1449
+ logger.trace(pickler, "# Su")
1450
+ return
1451
+
1452
+ if IS_PYPY:
1453
+ @register(MethodType)
1454
+ def save_instancemethod0(pickler, obj):
1455
+ code = getattr(obj.__func__, '__code__', None)
1456
+ if code is not None and type(code) is not CodeType \
1457
+ and getattr(obj.__self__, obj.__name__) == obj:
1458
+ # Some PyPy builtin functions have no module name
1459
+ logger.trace(pickler, "Me2: %s", obj)
1460
+ # TODO: verify that this works for all PyPy builtin methods
1461
+ pickler.save_reduce(getattr, (obj.__self__, obj.__name__), obj=obj)
1462
+ logger.trace(pickler, "# Me2")
1463
+ return
1464
+
1465
+ logger.trace(pickler, "Me1: %s", obj)
1466
+ pickler.save_reduce(MethodType, (obj.__func__, obj.__self__), obj=obj)
1467
+ logger.trace(pickler, "# Me1")
1468
+ return
1469
+ else:
1470
+ @register(MethodType)
1471
+ def save_instancemethod0(pickler, obj):
1472
+ logger.trace(pickler, "Me1: %s", obj)
1473
+ pickler.save_reduce(MethodType, (obj.__func__, obj.__self__), obj=obj)
1474
+ logger.trace(pickler, "# Me1")
1475
+ return
1476
+
1477
+ if not IS_PYPY:
1478
+ @register(MemberDescriptorType)
1479
+ @register(GetSetDescriptorType)
1480
+ @register(MethodDescriptorType)
1481
+ @register(WrapperDescriptorType)
1482
+ @register(ClassMethodDescriptorType)
1483
+ def save_wrapper_descriptor(pickler, obj):
1484
+ logger.trace(pickler, "Wr: %s", obj)
1485
+ pickler.save_reduce(_getattr, (obj.__objclass__, obj.__name__,
1486
+ obj.__repr__()), obj=obj)
1487
+ logger.trace(pickler, "# Wr")
1488
+ return
1489
+ else:
1490
+ @register(MemberDescriptorType)
1491
+ @register(GetSetDescriptorType)
1492
+ def save_wrapper_descriptor(pickler, obj):
1493
+ logger.trace(pickler, "Wr: %s", obj)
1494
+ pickler.save_reduce(_getattr, (obj.__objclass__, obj.__name__,
1495
+ obj.__repr__()), obj=obj)
1496
+ logger.trace(pickler, "# Wr")
1497
+ return
1498
+
1499
+ @register(CellType)
1500
+ def save_cell(pickler, obj):
1501
+ try:
1502
+ f = obj.cell_contents
1503
+ except ValueError: # cell is empty
1504
+ logger.trace(pickler, "Ce3: %s", obj)
1505
+ # _shims._CELL_EMPTY is defined in _shims.py to support PyPy 2.7.
1506
+ # It unpickles to a sentinel object _dill._CELL_EMPTY, also created in
1507
+ # _shims.py. This object is not present in Python 3 because the cell's
1508
+ # contents can be deleted in newer versions of Python. The reduce object
1509
+ # will instead unpickle to None if unpickled in Python 3.
1510
+
1511
+ # When breaking changes are made to dill, (_shims._CELL_EMPTY,) can
1512
+ # be replaced by () OR the delattr function can be removed repending on
1513
+ # whichever is more convienient.
1514
+ pickler.save_reduce(_create_cell, (_shims._CELL_EMPTY,), obj=obj)
1515
+ # Call the function _delattr on the cell's cell_contents attribute
1516
+ # The result of this function call will be None
1517
+ pickler.save_reduce(_shims._delattr, (obj, 'cell_contents'))
1518
+ # pop None created by calling _delattr off stack
1519
+ pickler.write(POP)
1520
+ logger.trace(pickler, "# Ce3")
1521
+ return
1522
+ if is_dill(pickler, child=True):
1523
+ if id(f) in pickler._postproc:
1524
+ # Already seen. Add to its postprocessing.
1525
+ postproc = pickler._postproc[id(f)]
1526
+ else:
1527
+ # Haven't seen it. Add to the highest possible object and set its
1528
+ # value as late as possible to prevent cycle.
1529
+ postproc = next(iter(pickler._postproc.values()), None)
1530
+ if postproc is not None:
1531
+ logger.trace(pickler, "Ce2: %s", obj)
1532
+ # _CELL_REF is defined in _shims.py to support older versions of
1533
+ # dill. When breaking changes are made to dill, (_CELL_REF,) can
1534
+ # be replaced by ()
1535
+ pickler.save_reduce(_create_cell, (_CELL_REF,), obj=obj)
1536
+ postproc.append((_shims._setattr, (obj, 'cell_contents', f)))
1537
+ logger.trace(pickler, "# Ce2")
1538
+ return
1539
+ logger.trace(pickler, "Ce1: %s", obj)
1540
+ pickler.save_reduce(_create_cell, (f,), obj=obj)
1541
+ logger.trace(pickler, "# Ce1")
1542
+ return
1543
+
1544
+ if MAPPING_PROXY_TRICK:
1545
+ @register(DictProxyType)
1546
+ def save_dictproxy(pickler, obj):
1547
+ logger.trace(pickler, "Mp: %s", _repr_dict(obj)) # obj
1548
+ mapping = obj | _dictproxy_helper_instance
1549
+ pickler.save_reduce(DictProxyType, (mapping,), obj=obj)
1550
+ logger.trace(pickler, "# Mp")
1551
+ return
1552
+ else:
1553
+ @register(DictProxyType)
1554
+ def save_dictproxy(pickler, obj):
1555
+ logger.trace(pickler, "Mp: %s", _repr_dict(obj)) # obj
1556
+ pickler.save_reduce(DictProxyType, (obj.copy(),), obj=obj)
1557
+ logger.trace(pickler, "# Mp")
1558
+ return
1559
+
1560
+ @register(SliceType)
1561
+ def save_slice(pickler, obj):
1562
+ logger.trace(pickler, "Sl: %s", obj)
1563
+ pickler.save_reduce(slice, (obj.start, obj.stop, obj.step), obj=obj)
1564
+ logger.trace(pickler, "# Sl")
1565
+ return
1566
+
1567
+ @register(XRangeType)
1568
+ @register(EllipsisType)
1569
+ @register(NotImplementedType)
1570
+ def save_singleton(pickler, obj):
1571
+ logger.trace(pickler, "Si: %s", obj)
1572
+ pickler.save_reduce(_eval_repr, (obj.__repr__(),), obj=obj)
1573
+ logger.trace(pickler, "# Si")
1574
+ return
1575
+
1576
+ def _proxy_helper(obj): # a dead proxy returns a reference to None
1577
+ """get memory address of proxy's reference object"""
1578
+ _repr = repr(obj)
1579
+ try: _str = str(obj)
1580
+ except ReferenceError: # it's a dead proxy
1581
+ return id(None)
1582
+ if _str == _repr: return id(obj) # it's a repr
1583
+ try: # either way, it's a proxy from here
1584
+ address = int(_str.rstrip('>').split(' at ')[-1], base=16)
1585
+ except ValueError: # special case: proxy of a 'type'
1586
+ if not IS_PYPY:
1587
+ address = int(_repr.rstrip('>').split(' at ')[-1], base=16)
1588
+ else:
1589
+ objects = iter(gc.get_objects())
1590
+ for _obj in objects:
1591
+ if repr(_obj) == _str: return id(_obj)
1592
+ # all bad below... nothing found so throw ReferenceError
1593
+ msg = "Cannot reference object for proxy at '%s'" % id(obj)
1594
+ raise ReferenceError(msg)
1595
+ return address
1596
+
1597
+ def _locate_object(address, module=None):
1598
+ """get object located at the given memory address (inverse of id(obj))"""
1599
+ special = [None, True, False] #XXX: more...?
1600
+ for obj in special:
1601
+ if address == id(obj): return obj
1602
+ if module:
1603
+ objects = iter(module.__dict__.values())
1604
+ else: objects = iter(gc.get_objects())
1605
+ for obj in objects:
1606
+ if address == id(obj): return obj
1607
+ # all bad below... nothing found so throw ReferenceError or TypeError
1608
+ try: address = hex(address)
1609
+ except TypeError:
1610
+ raise TypeError("'%s' is not a valid memory address" % str(address))
1611
+ raise ReferenceError("Cannot reference object at '%s'" % address)
1612
+
1613
+ @register(ReferenceType)
1614
+ def save_weakref(pickler, obj):
1615
+ refobj = obj()
1616
+ logger.trace(pickler, "R1: %s", obj)
1617
+ #refobj = ctypes.pythonapi.PyWeakref_GetObject(obj) # dead returns "None"
1618
+ pickler.save_reduce(_create_weakref, (refobj,), obj=obj)
1619
+ logger.trace(pickler, "# R1")
1620
+ return
1621
+
1622
+ @register(ProxyType)
1623
+ @register(CallableProxyType)
1624
+ def save_weakproxy(pickler, obj):
1625
+ # Must do string substitution here and use %r to avoid ReferenceError.
1626
+ logger.trace(pickler, "R2: %r" % obj)
1627
+ refobj = _locate_object(_proxy_helper(obj))
1628
+ pickler.save_reduce(_create_weakproxy, (refobj, callable(obj)), obj=obj)
1629
+ logger.trace(pickler, "# R2")
1630
+ return
1631
+
1632
+ def _is_builtin_module(module):
1633
+ if not hasattr(module, "__file__"): return True
1634
+ if module.__file__ is None: return False
1635
+ # If a module file name starts with prefix, it should be a builtin
1636
+ # module, so should always be pickled as a reference.
1637
+ names = ["base_prefix", "base_exec_prefix", "exec_prefix", "prefix", "real_prefix"]
1638
+ rp = os.path.realpath
1639
+ # See https://github.com/uqfoundation/dill/issues/566
1640
+ return (
1641
+ any(
1642
+ module.__file__.startswith(getattr(sys, name))
1643
+ or rp(module.__file__).startswith(rp(getattr(sys, name)))
1644
+ for name in names
1645
+ if hasattr(sys, name)
1646
+ )
1647
+ or module.__file__.endswith(EXTENSION_SUFFIXES)
1648
+ or 'site-packages' in module.__file__
1649
+ )
1650
+
1651
+ def _is_imported_module(module):
1652
+ return getattr(module, '__loader__', None) is not None or module in sys.modules.values()
1653
+
1654
+ @register(ModuleType)
1655
+ def save_module(pickler, obj):
1656
+ if False: #_use_diff:
1657
+ if obj.__name__.split('.', 1)[0] != "dill":
1658
+ try:
1659
+ changed = diff.whats_changed(obj, seen=pickler._diff_cache)[0]
1660
+ except RuntimeError: # not memorised module, probably part of dill
1661
+ pass
1662
+ else:
1663
+ logger.trace(pickler, "M2: %s with diff", obj)
1664
+ logger.info("Diff: %s", changed.keys())
1665
+ pickler.save_reduce(_import_module, (obj.__name__,), obj=obj,
1666
+ state=changed)
1667
+ logger.trace(pickler, "# M2")
1668
+ return
1669
+
1670
+ logger.trace(pickler, "M1: %s", obj)
1671
+ pickler.save_reduce(_import_module, (obj.__name__,), obj=obj)
1672
+ logger.trace(pickler, "# M1")
1673
+ else:
1674
+ builtin_mod = _is_builtin_module(obj)
1675
+ is_session_main = is_dill(pickler, child=True) and obj is pickler._main
1676
+ if (obj.__name__ not in ("builtins", "dill", "dill._dill") and not builtin_mod
1677
+ or is_session_main):
1678
+ logger.trace(pickler, "M1: %s", obj)
1679
+ # Hack for handling module-type objects in load_module().
1680
+ mod_name = obj.__name__ if _is_imported_module(obj) else '__runtime__.%s' % obj.__name__
1681
+ # Second references are saved as __builtin__.__main__ in save_module_dict().
1682
+ main_dict = obj.__dict__.copy()
1683
+ for item in ('__builtins__', '__loader__'):
1684
+ main_dict.pop(item, None)
1685
+ for item in IPYTHON_SINGLETONS: #pragma: no cover
1686
+ if getattr(main_dict.get(item), '__module__', '').startswith('IPython'):
1687
+ del main_dict[item]
1688
+ pickler.save_reduce(_import_module, (mod_name,), obj=obj, state=main_dict)
1689
+ logger.trace(pickler, "# M1")
1690
+ elif obj.__name__ == "dill._dill":
1691
+ logger.trace(pickler, "M2: %s", obj)
1692
+ pickler.save_global(obj, name="_dill")
1693
+ logger.trace(pickler, "# M2")
1694
+ else:
1695
+ logger.trace(pickler, "M2: %s", obj)
1696
+ pickler.save_reduce(_import_module, (obj.__name__,), obj=obj)
1697
+ logger.trace(pickler, "# M2")
1698
+ return
1699
+
1700
+ # The following function is based on '_extract_class_dict' from 'cloudpickle'
1701
+ # Copyright (c) 2012, Regents of the University of California.
1702
+ # Copyright (c) 2009 `PiCloud, Inc. <http://www.picloud.com>`_.
1703
+ # License: https://github.com/cloudpipe/cloudpickle/blob/master/LICENSE
1704
+ def _get_typedict_type(cls, clsdict, attrs, postproc_list):
1705
+ """Retrieve a copy of the dict of a class without the inherited methods"""
1706
+ if len(cls.__bases__) == 1:
1707
+ inherited_dict = cls.__bases__[0].__dict__
1708
+ else:
1709
+ inherited_dict = {}
1710
+ for base in reversed(cls.__bases__):
1711
+ inherited_dict.update(base.__dict__)
1712
+ to_remove = []
1713
+ for name, value in dict.items(clsdict):
1714
+ try:
1715
+ base_value = inherited_dict[name]
1716
+ if value is base_value and hasattr(value, '__qualname__'):
1717
+ to_remove.append(name)
1718
+ except KeyError:
1719
+ pass
1720
+ for name in to_remove:
1721
+ dict.pop(clsdict, name)
1722
+
1723
+ if issubclass(type(cls), type):
1724
+ clsdict.pop('__dict__', None)
1725
+ clsdict.pop('__weakref__', None)
1726
+ # clsdict.pop('__prepare__', None)
1727
+ return clsdict, attrs
1728
+
1729
+ def _get_typedict_abc(obj, _dict, attrs, postproc_list):
1730
+ if hasattr(abc, '_get_dump'):
1731
+ (registry, _, _, _) = abc._get_dump(obj)
1732
+ register = obj.register
1733
+ postproc_list.extend((register, (reg(),)) for reg in registry)
1734
+ elif hasattr(obj, '_abc_registry'):
1735
+ registry = obj._abc_registry
1736
+ register = obj.register
1737
+ postproc_list.extend((register, (reg,)) for reg in registry)
1738
+ else:
1739
+ raise PicklingError("Cannot find registry of ABC %s", obj)
1740
+
1741
+ if '_abc_registry' in _dict:
1742
+ _dict.pop('_abc_registry', None)
1743
+ _dict.pop('_abc_cache', None)
1744
+ _dict.pop('_abc_negative_cache', None)
1745
+ # _dict.pop('_abc_negative_cache_version', None)
1746
+ else:
1747
+ _dict.pop('_abc_impl', None)
1748
+ return _dict, attrs
1749
+
1750
+ @register(TypeType)
1751
+ def save_type(pickler, obj, postproc_list=None):
1752
+ if obj in _typemap:
1753
+ logger.trace(pickler, "T1: %s", obj)
1754
+ # if obj in _incedental_types:
1755
+ # warnings.warn('Type %r may only exist on this implementation of Python and cannot be unpickled in other implementations.' % (obj,), PicklingWarning)
1756
+ pickler.save_reduce(_load_type, (_typemap[obj],), obj=obj)
1757
+ logger.trace(pickler, "# T1")
1758
+ elif obj.__bases__ == (tuple,) and all([hasattr(obj, attr) for attr in ('_fields','_asdict','_make','_replace')]):
1759
+ # special case: namedtuples
1760
+ logger.trace(pickler, "T6: %s", obj)
1761
+
1762
+ obj_name = getattr(obj, '__qualname__', getattr(obj, '__name__', None))
1763
+ if obj.__name__ != obj_name:
1764
+ if postproc_list is None:
1765
+ postproc_list = []
1766
+ postproc_list.append((setattr, (obj, '__qualname__', obj_name)))
1767
+
1768
+ if not obj._field_defaults:
1769
+ _save_with_postproc(pickler, (_create_namedtuple, (obj.__name__, obj._fields, obj.__module__)), obj=obj, postproc_list=postproc_list)
1770
+ else:
1771
+ defaults = [obj._field_defaults[field] for field in obj._fields if field in obj._field_defaults]
1772
+ _save_with_postproc(pickler, (_create_namedtuple, (obj.__name__, obj._fields, obj.__module__, defaults)), obj=obj, postproc_list=postproc_list)
1773
+ logger.trace(pickler, "# T6")
1774
+ return
1775
+
1776
+ # special cases: NoneType, NotImplementedType, EllipsisType, EnumMeta
1777
+ elif obj is type(None):
1778
+ logger.trace(pickler, "T7: %s", obj)
1779
+ #XXX: pickler.save_reduce(type, (None,), obj=obj)
1780
+ pickler.write(GLOBAL + b'__builtin__\nNoneType\n')
1781
+ logger.trace(pickler, "# T7")
1782
+ elif obj is NotImplementedType:
1783
+ logger.trace(pickler, "T7: %s", obj)
1784
+ pickler.save_reduce(type, (NotImplemented,), obj=obj)
1785
+ logger.trace(pickler, "# T7")
1786
+ elif obj is EllipsisType:
1787
+ logger.trace(pickler, "T7: %s", obj)
1788
+ pickler.save_reduce(type, (Ellipsis,), obj=obj)
1789
+ logger.trace(pickler, "# T7")
1790
+ elif obj is EnumMeta:
1791
+ logger.trace(pickler, "T7: %s", obj)
1792
+ pickler.write(GLOBAL + b'enum\nEnumMeta\n')
1793
+ logger.trace(pickler, "# T7")
1794
+
1795
+ else:
1796
+ _byref = getattr(pickler, '_byref', None)
1797
+ obj_recursive = id(obj) in getattr(pickler, '_postproc', ())
1798
+ incorrectly_named = not _locate_function(obj, pickler)
1799
+ if not _byref and not obj_recursive and incorrectly_named: # not a function, but the name was held over
1800
+ if postproc_list is None:
1801
+ postproc_list = []
1802
+
1803
+ # thanks to Tom Stepleton pointing out pickler._session unneeded
1804
+ logger.trace(pickler, "T2: %s", obj)
1805
+ _dict, attrs = _get_typedict_type(obj, obj.__dict__.copy(), None, postproc_list) # copy dict proxy to a dict
1806
+
1807
+ #print (_dict)
1808
+ #print ("%s\n%s" % (type(obj), obj.__name__))
1809
+ #print ("%s\n%s" % (obj.__bases__, obj.__dict__))
1810
+ slots = _dict.get('__slots__', ())
1811
+ if type(slots) == str:
1812
+ # __slots__ accepts a single string
1813
+ slots = (slots,)
1814
+
1815
+ for name in slots:
1816
+ _dict.pop(name, None)
1817
+
1818
+ if isinstance(obj, abc.ABCMeta):
1819
+ logger.trace(pickler, "ABC: %s", obj)
1820
+ _dict, attrs = _get_typedict_abc(obj, _dict, attrs, postproc_list)
1821
+ logger.trace(pickler, "# ABC")
1822
+
1823
+ qualname = getattr(obj, '__qualname__', None)
1824
+ if attrs is not None:
1825
+ for k, v in attrs.items():
1826
+ postproc_list.append((setattr, (obj, k, v)))
1827
+ # TODO: Consider using the state argument to save_reduce?
1828
+ if qualname is not None:
1829
+ postproc_list.append((setattr, (obj, '__qualname__', qualname)))
1830
+
1831
+ if not hasattr(obj, '__orig_bases__'):
1832
+ _save_with_postproc(pickler, (_create_type, (
1833
+ type(obj), obj.__name__, obj.__bases__, _dict
1834
+ )), obj=obj, postproc_list=postproc_list)
1835
+ else:
1836
+ # This case will always work, but might be overkill.
1837
+ _metadict = {
1838
+ 'metaclass': type(obj)
1839
+ }
1840
+
1841
+ if _dict:
1842
+ _dict_update = PartialType(_setitems, source=_dict)
1843
+ else:
1844
+ _dict_update = None
1845
+
1846
+ _save_with_postproc(pickler, (new_class, (
1847
+ obj.__name__, obj.__orig_bases__, _metadict, _dict_update
1848
+ )), obj=obj, postproc_list=postproc_list)
1849
+ logger.trace(pickler, "# T2")
1850
+ else:
1851
+ obj_name = getattr(obj, '__qualname__', getattr(obj, '__name__', None))
1852
+ logger.trace(pickler, "T4: %s", obj)
1853
+ if incorrectly_named:
1854
+ warnings.warn(
1855
+ "Cannot locate reference to %r." % (obj,),
1856
+ PicklingWarning,
1857
+ stacklevel=3,
1858
+ )
1859
+ if obj_recursive:
1860
+ warnings.warn(
1861
+ "Cannot pickle %r: %s.%s has recursive self-references that "
1862
+ "trigger a RecursionError." % (obj, obj.__module__, obj_name),
1863
+ PicklingWarning,
1864
+ stacklevel=3,
1865
+ )
1866
+ #print (obj.__dict__)
1867
+ #print ("%s\n%s" % (type(obj), obj.__name__))
1868
+ #print ("%s\n%s" % (obj.__bases__, obj.__dict__))
1869
+ StockPickler.save_global(pickler, obj, name=obj_name)
1870
+ logger.trace(pickler, "# T4")
1871
+ return
1872
+
1873
+ @register(property)
1874
+ @register(abc.abstractproperty)
1875
+ def save_property(pickler, obj):
1876
+ logger.trace(pickler, "Pr: %s", obj)
1877
+ pickler.save_reduce(type(obj), (obj.fget, obj.fset, obj.fdel, obj.__doc__),
1878
+ obj=obj)
1879
+ logger.trace(pickler, "# Pr")
1880
+
1881
+ @register(staticmethod)
1882
+ @register(classmethod)
1883
+ @register(abc.abstractstaticmethod)
1884
+ @register(abc.abstractclassmethod)
1885
+ def save_classmethod(pickler, obj):
1886
+ logger.trace(pickler, "Cm: %s", obj)
1887
+ orig_func = obj.__func__
1888
+
1889
+ # if type(obj.__dict__) is dict:
1890
+ # if obj.__dict__:
1891
+ # state = obj.__dict__
1892
+ # else:
1893
+ # state = None
1894
+ # else:
1895
+ # state = (None, {'__dict__', obj.__dict__})
1896
+
1897
+ pickler.save_reduce(type(obj), (orig_func,), obj=obj)
1898
+ logger.trace(pickler, "# Cm")
1899
+
1900
+ @register(FunctionType)
1901
+ def save_function(pickler, obj):
1902
+ if not _locate_function(obj, pickler):
1903
+ if type(obj.__code__) is not CodeType:
1904
+ # Some PyPy builtin functions have no module name, and thus are not
1905
+ # able to be located
1906
+ module_name = getattr(obj, '__module__', None)
1907
+ if module_name is None:
1908
+ module_name = __builtin__.__name__
1909
+ module = _import_module(module_name, safe=True)
1910
+ _pypy_builtin = False
1911
+ try:
1912
+ found, _ = _getattribute(module, obj.__qualname__)
1913
+ if getattr(found, '__func__', None) is obj:
1914
+ _pypy_builtin = True
1915
+ except AttributeError:
1916
+ pass
1917
+
1918
+ if _pypy_builtin:
1919
+ logger.trace(pickler, "F3: %s", obj)
1920
+ pickler.save_reduce(getattr, (found, '__func__'), obj=obj)
1921
+ logger.trace(pickler, "# F3")
1922
+ return
1923
+
1924
+ logger.trace(pickler, "F1: %s", obj)
1925
+ _recurse = getattr(pickler, '_recurse', None)
1926
+ _postproc = getattr(pickler, '_postproc', None)
1927
+ _main_modified = getattr(pickler, '_main_modified', None)
1928
+ _original_main = getattr(pickler, '_original_main', __builtin__)#'None'
1929
+ postproc_list = []
1930
+ if _recurse:
1931
+ # recurse to get all globals referred to by obj
1932
+ from .detect import globalvars
1933
+ globs_copy = globalvars(obj, recurse=True, builtin=True)
1934
+
1935
+ # Add the name of the module to the globs dictionary to prevent
1936
+ # the duplication of the dictionary. Pickle the unpopulated
1937
+ # globals dictionary and set the remaining items after the function
1938
+ # is created to correctly handle recursion.
1939
+ globs = {'__name__': obj.__module__}
1940
+ else:
1941
+ globs_copy = obj.__globals__
1942
+
1943
+ # If the globals is the __dict__ from the module being saved as a
1944
+ # session, substitute it by the dictionary being actually saved.
1945
+ if _main_modified and globs_copy is _original_main.__dict__:
1946
+ globs_copy = getattr(pickler, '_main', _original_main).__dict__
1947
+ globs = globs_copy
1948
+ # If the globals is a module __dict__, do not save it in the pickle.
1949
+ elif globs_copy is not None and obj.__module__ is not None and \
1950
+ getattr(_import_module(obj.__module__, True), '__dict__', None) is globs_copy:
1951
+ globs = globs_copy
1952
+ else:
1953
+ globs = {'__name__': obj.__module__}
1954
+
1955
+ if globs_copy is not None and globs is not globs_copy:
1956
+ # In the case that the globals are copied, we need to ensure that
1957
+ # the globals dictionary is updated when all objects in the
1958
+ # dictionary are already created.
1959
+ glob_ids = {id(g) for g in globs_copy.values()}
1960
+ for stack_element in _postproc:
1961
+ if stack_element in glob_ids:
1962
+ _postproc[stack_element].append((_setitems, (globs, globs_copy)))
1963
+ break
1964
+ else:
1965
+ postproc_list.append((_setitems, (globs, globs_copy)))
1966
+
1967
+ closure = obj.__closure__
1968
+ state_dict = {}
1969
+ for fattrname in ('__doc__', '__kwdefaults__', '__annotations__'):
1970
+ fattr = getattr(obj, fattrname, None)
1971
+ if fattr is not None:
1972
+ state_dict[fattrname] = fattr
1973
+ if obj.__qualname__ != obj.__name__:
1974
+ state_dict['__qualname__'] = obj.__qualname__
1975
+ if '__name__' not in globs or obj.__module__ != globs['__name__']:
1976
+ state_dict['__module__'] = obj.__module__
1977
+
1978
+ state = obj.__dict__
1979
+ if type(state) is not dict:
1980
+ state_dict['__dict__'] = state
1981
+ state = None
1982
+ if state_dict:
1983
+ state = state, state_dict
1984
+
1985
+ _save_with_postproc(pickler, (_create_function, (
1986
+ obj.__code__, globs, obj.__name__, obj.__defaults__,
1987
+ closure
1988
+ ), state), obj=obj, postproc_list=postproc_list)
1989
+
1990
+ # Lift closure cell update to earliest function (#458)
1991
+ if _postproc:
1992
+ topmost_postproc = next(iter(_postproc.values()), None)
1993
+ if closure and topmost_postproc:
1994
+ for cell in closure:
1995
+ possible_postproc = (setattr, (cell, 'cell_contents', obj))
1996
+ try:
1997
+ topmost_postproc.remove(possible_postproc)
1998
+ except ValueError:
1999
+ continue
2000
+
2001
+ # Change the value of the cell
2002
+ pickler.save_reduce(*possible_postproc)
2003
+ # pop None created by calling preprocessing step off stack
2004
+ pickler.write(POP)
2005
+
2006
+ logger.trace(pickler, "# F1")
2007
+ else:
2008
+ logger.trace(pickler, "F2: %s", obj)
2009
+ name = getattr(obj, '__qualname__', getattr(obj, '__name__', None))
2010
+ StockPickler.save_global(pickler, obj, name=name)
2011
+ logger.trace(pickler, "# F2")
2012
+ return
2013
+
2014
+ if HAS_CTYPES and hasattr(ctypes, 'pythonapi'):
2015
+ _PyCapsule_New = ctypes.pythonapi.PyCapsule_New
2016
+ _PyCapsule_New.argtypes = (ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p)
2017
+ _PyCapsule_New.restype = ctypes.py_object
2018
+ _PyCapsule_GetPointer = ctypes.pythonapi.PyCapsule_GetPointer
2019
+ _PyCapsule_GetPointer.argtypes = (ctypes.py_object, ctypes.c_char_p)
2020
+ _PyCapsule_GetPointer.restype = ctypes.c_void_p
2021
+ _PyCapsule_GetDestructor = ctypes.pythonapi.PyCapsule_GetDestructor
2022
+ _PyCapsule_GetDestructor.argtypes = (ctypes.py_object,)
2023
+ _PyCapsule_GetDestructor.restype = ctypes.c_void_p
2024
+ _PyCapsule_GetContext = ctypes.pythonapi.PyCapsule_GetContext
2025
+ _PyCapsule_GetContext.argtypes = (ctypes.py_object,)
2026
+ _PyCapsule_GetContext.restype = ctypes.c_void_p
2027
+ _PyCapsule_GetName = ctypes.pythonapi.PyCapsule_GetName
2028
+ _PyCapsule_GetName.argtypes = (ctypes.py_object,)
2029
+ _PyCapsule_GetName.restype = ctypes.c_char_p
2030
+ _PyCapsule_IsValid = ctypes.pythonapi.PyCapsule_IsValid
2031
+ _PyCapsule_IsValid.argtypes = (ctypes.py_object, ctypes.c_char_p)
2032
+ _PyCapsule_IsValid.restype = ctypes.c_bool
2033
+ _PyCapsule_SetContext = ctypes.pythonapi.PyCapsule_SetContext
2034
+ _PyCapsule_SetContext.argtypes = (ctypes.py_object, ctypes.c_void_p)
2035
+ _PyCapsule_SetDestructor = ctypes.pythonapi.PyCapsule_SetDestructor
2036
+ _PyCapsule_SetDestructor.argtypes = (ctypes.py_object, ctypes.c_void_p)
2037
+ _PyCapsule_SetName = ctypes.pythonapi.PyCapsule_SetName
2038
+ _PyCapsule_SetName.argtypes = (ctypes.py_object, ctypes.c_char_p)
2039
+ _PyCapsule_SetPointer = ctypes.pythonapi.PyCapsule_SetPointer
2040
+ _PyCapsule_SetPointer.argtypes = (ctypes.py_object, ctypes.c_void_p)
2041
+ #from _socket import CAPI as _testcapsule
2042
+ _testcapsule_name = b'dill._dill._testcapsule'
2043
+ _testcapsule = _PyCapsule_New(
2044
+ ctypes.cast(_PyCapsule_New, ctypes.c_void_p),
2045
+ ctypes.c_char_p(_testcapsule_name),
2046
+ None
2047
+ )
2048
+ PyCapsuleType = type(_testcapsule)
2049
+ @register(PyCapsuleType)
2050
+ def save_capsule(pickler, obj):
2051
+ logger.trace(pickler, "Cap: %s", obj)
2052
+ name = _PyCapsule_GetName(obj)
2053
+ #warnings.warn('Pickling a PyCapsule (%s) does not pickle any C data structures and could cause segmentation faults or other memory errors when unpickling.' % (name,), PicklingWarning)
2054
+ pointer = _PyCapsule_GetPointer(obj, name)
2055
+ context = _PyCapsule_GetContext(obj)
2056
+ destructor = _PyCapsule_GetDestructor(obj)
2057
+ pickler.save_reduce(_create_capsule, (pointer, name, context, destructor), obj=obj)
2058
+ logger.trace(pickler, "# Cap")
2059
+ _incedental_reverse_typemap['PyCapsuleType'] = PyCapsuleType
2060
+ _reverse_typemap['PyCapsuleType'] = PyCapsuleType
2061
+ _incedental_types.add(PyCapsuleType)
2062
+ else:
2063
+ _testcapsule = None
2064
+
2065
+
2066
+ #############################
2067
+ # A quick fix for issue #500
2068
+ # This should be removed when a better solution is found.
2069
+
2070
+ if hasattr(dataclasses, "_HAS_DEFAULT_FACTORY_CLASS"):
2071
+ @register(dataclasses._HAS_DEFAULT_FACTORY_CLASS)
2072
+ def save_dataclasses_HAS_DEFAULT_FACTORY_CLASS(pickler, obj):
2073
+ logger.trace(pickler, "DcHDF: %s", obj)
2074
+ pickler.write(GLOBAL + b"dataclasses\n_HAS_DEFAULT_FACTORY\n")
2075
+ logger.trace(pickler, "# DcHDF")
2076
+
2077
+ if hasattr(dataclasses, "MISSING"):
2078
+ @register(type(dataclasses.MISSING))
2079
+ def save_dataclasses_MISSING_TYPE(pickler, obj):
2080
+ logger.trace(pickler, "DcM: %s", obj)
2081
+ pickler.write(GLOBAL + b"dataclasses\nMISSING\n")
2082
+ logger.trace(pickler, "# DcM")
2083
+
2084
+ if hasattr(dataclasses, "KW_ONLY"):
2085
+ @register(type(dataclasses.KW_ONLY))
2086
+ def save_dataclasses_KW_ONLY_TYPE(pickler, obj):
2087
+ logger.trace(pickler, "DcKWO: %s", obj)
2088
+ pickler.write(GLOBAL + b"dataclasses\nKW_ONLY\n")
2089
+ logger.trace(pickler, "# DcKWO")
2090
+
2091
+ if hasattr(dataclasses, "_FIELD_BASE"):
2092
+ @register(dataclasses._FIELD_BASE)
2093
+ def save_dataclasses_FIELD_BASE(pickler, obj):
2094
+ logger.trace(pickler, "DcFB: %s", obj)
2095
+ pickler.write(GLOBAL + b"dataclasses\n" + obj.name.encode() + b"\n")
2096
+ logger.trace(pickler, "# DcFB")
2097
+
2098
+ #############################
2099
+
2100
+ # quick sanity checking
2101
+ def pickles(obj,exact=False,safe=False,**kwds):
2102
+ """
2103
+ Quick check if object pickles with dill.
2104
+
2105
+ If *exact=True* then an equality test is done to check if the reconstructed
2106
+ object matches the original object.
2107
+
2108
+ If *safe=True* then any exception will raised in copy signal that the
2109
+ object is not picklable, otherwise only pickling errors will be trapped.
2110
+
2111
+ Additional keyword arguments are as :func:`dumps` and :func:`loads`.
2112
+ """
2113
+ if safe: exceptions = (Exception,) # RuntimeError, ValueError
2114
+ else:
2115
+ exceptions = (TypeError, AssertionError, NotImplementedError, PicklingError, UnpicklingError)
2116
+ try:
2117
+ pik = copy(obj, **kwds)
2118
+ #FIXME: should check types match first, then check content if "exact"
2119
+ try:
2120
+ #FIXME: should be "(pik == obj).all()" for numpy comparison, though that'll fail if shapes differ
2121
+ result = bool(pik.all() == obj.all())
2122
+ except (AttributeError, TypeError):
2123
+ warnings.filterwarnings('ignore') #FIXME: be specific
2124
+ result = pik == obj
2125
+ if warnings.filters: del warnings.filters[0]
2126
+ if hasattr(result, 'toarray'): # for unusual types like sparse matrix
2127
+ result = result.toarray().all()
2128
+ if result: return True
2129
+ if not exact:
2130
+ result = type(pik) == type(obj)
2131
+ if result: return result
2132
+ # class instances might have been dumped with byref=False
2133
+ return repr(type(pik)) == repr(type(obj)) #XXX: InstanceType?
2134
+ return False
2135
+ except exceptions:
2136
+ return False
2137
+
2138
+ def check(obj, *args, **kwds):
2139
+ """
2140
+ Check pickling of an object across another process.
2141
+
2142
+ *python* is the path to the python interpreter (defaults to sys.executable)
2143
+
2144
+ Set *verbose=True* to print the unpickled object in the other process.
2145
+
2146
+ Additional keyword arguments are as :func:`dumps` and :func:`loads`.
2147
+ """
2148
+ # == undocumented ==
2149
+ # python -- the string path or executable name of the selected python
2150
+ # verbose -- if True, be verbose about printing warning messages
2151
+ # all other args and kwds are passed to dill.dumps #FIXME: ignore on load
2152
+ verbose = kwds.pop('verbose', False)
2153
+ python = kwds.pop('python', None)
2154
+ if python is None:
2155
+ import sys
2156
+ python = sys.executable
2157
+ # type check
2158
+ isinstance(python, str)
2159
+ import subprocess
2160
+ fail = True
2161
+ try:
2162
+ _obj = dumps(obj, *args, **kwds)
2163
+ fail = False
2164
+ finally:
2165
+ if fail and verbose:
2166
+ print("DUMP FAILED")
2167
+ #FIXME: fails if python interpreter path contains spaces
2168
+ # Use the following instead (which also processes the 'ignore' keyword):
2169
+ # ignore = kwds.pop('ignore', None)
2170
+ # unpickle = "dill.loads(%s, ignore=%s)"%(repr(_obj), repr(ignore))
2171
+ # cmd = [python, "-c", "import dill; print(%s)"%unpickle]
2172
+ # msg = "SUCCESS" if not subprocess.call(cmd) else "LOAD FAILED"
2173
+ msg = "%s -c import dill; print(dill.loads(%s))" % (python, repr(_obj))
2174
+ msg = "SUCCESS" if not subprocess.call(msg.split(None,2)) else "LOAD FAILED"
2175
+ if verbose:
2176
+ print(msg)
2177
+ return
2178
+
2179
+ # use to protect against missing attributes
2180
+ def is_dill(pickler, child=None):
2181
+ "check the dill-ness of your pickler"
2182
+ if child is False or not hasattr(pickler.__class__, 'mro'):
2183
+ return 'dill' in pickler.__module__
2184
+ return Pickler in pickler.__class__.mro()
2185
+
2186
+ def _extend():
2187
+ """extend pickle with all of dill's registered types"""
2188
+ # need to have pickle not choke on _main_module? use is_dill(pickler)
2189
+ for t,func in Pickler.dispatch.items():
2190
+ try:
2191
+ StockPickler.dispatch[t] = func
2192
+ except Exception: #TypeError, PicklingError, UnpicklingError
2193
+ logger.trace(pickler, "skip: %s", t)
2194
+ return
2195
+
2196
+ del diff, _use_diff, use_diff
2197
+
2198
+ # EOF
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/_objects.py ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2016 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+ """
9
+ all Python Standard Library objects (currently: CH 1-15 @ 2.7)
10
+ and some other common objects (i.e. numpy.ndarray)
11
+ """
12
+
13
+ __all__ = ['registered','failures','succeeds']
14
+
15
+ # helper imports
16
+ import warnings; warnings.filterwarnings("ignore", category=DeprecationWarning)
17
+ import sys
18
+ import queue as Queue
19
+ import dbm as anydbm
20
+ from io import BytesIO as StringIO
21
+ import re
22
+ import array
23
+ import collections
24
+ import codecs
25
+ import struct
26
+ import dataclasses
27
+ import datetime
28
+ import calendar
29
+ import weakref
30
+ import pprint
31
+ import decimal
32
+ import numbers
33
+ import functools
34
+ import itertools
35
+ import operator
36
+ import tempfile
37
+ import shelve
38
+ import zlib
39
+ import gzip
40
+ import zipfile
41
+ import tarfile
42
+ import csv
43
+ import hashlib
44
+ import hmac
45
+ import os
46
+ import logging
47
+ import logging.handlers
48
+ import optparse
49
+ #import __hello__
50
+ import threading
51
+ import socket
52
+ import contextlib
53
+ try:
54
+ import bz2
55
+ import sqlite3
56
+ import dbm.ndbm as dbm
57
+ HAS_ALL = True
58
+ except ImportError: # Ubuntu
59
+ HAS_ALL = False
60
+ try:
61
+ #import curses
62
+ #from curses import textpad, panel
63
+ HAS_CURSES = True
64
+ except ImportError: # Windows
65
+ HAS_CURSES = False
66
+ try:
67
+ import ctypes
68
+ HAS_CTYPES = True
69
+ # if using `pypy`, pythonapi is not found
70
+ IS_PYPY = not hasattr(ctypes, 'pythonapi')
71
+ except ImportError: # MacPorts
72
+ HAS_CTYPES = False
73
+ IS_PYPY = False
74
+
75
+ # helper objects
76
+ class _class:
77
+ def _method(self):
78
+ pass
79
+ # @classmethod
80
+ # def _clsmethod(cls): #XXX: test me
81
+ # pass
82
+ # @staticmethod
83
+ # def _static(self): #XXX: test me
84
+ # pass
85
+ class _class2:
86
+ def __call__(self):
87
+ pass
88
+ _instance2 = _class2()
89
+ class _newclass(object):
90
+ def _method(self):
91
+ pass
92
+ # @classmethod
93
+ # def _clsmethod(cls): #XXX: test me
94
+ # pass
95
+ # @staticmethod
96
+ # def _static(self): #XXX: test me
97
+ # pass
98
+ class _newclass2(object):
99
+ __slots__ = ['descriptor']
100
+ def _function(x): yield x
101
+ def _function2():
102
+ try: raise
103
+ except Exception:
104
+ from sys import exc_info
105
+ e, er, tb = exc_info()
106
+ return er, tb
107
+ if HAS_CTYPES:
108
+ class _Struct(ctypes.Structure):
109
+ pass
110
+ _Struct._fields_ = [("_field", ctypes.c_int),("next", ctypes.POINTER(_Struct))]
111
+ _filedescrip, _tempfile = tempfile.mkstemp('r') # deleted in cleanup
112
+ if sys.hexversion < 0x30d00a1:
113
+ _tmpf = tempfile.TemporaryFile('w') # emits OSError 9 in python 3.13
114
+ else:
115
+ _tmpf = tempfile.NamedTemporaryFile('w').file # for > python 3.9
116
+
117
+ # objects used by dill for type declaration
118
+ registered = d = {}
119
+ # objects dill fails to pickle
120
+ failures = x = {}
121
+ # all other type objects
122
+ succeeds = a = {}
123
+
124
+ # types module (part of CH 8)
125
+ a['BooleanType'] = bool(1)
126
+ a['BuiltinFunctionType'] = len
127
+ a['BuiltinMethodType'] = a['BuiltinFunctionType']
128
+ a['BytesType'] = _bytes = codecs.latin_1_encode('\x00')[0] # bytes(1)
129
+ a['ClassType'] = _class
130
+ a['ComplexType'] = complex(1)
131
+ a['DictType'] = _dict = {}
132
+ a['DictionaryType'] = a['DictType']
133
+ a['FloatType'] = float(1)
134
+ a['FunctionType'] = _function
135
+ a['InstanceType'] = _instance = _class()
136
+ a['IntType'] = _int = int(1)
137
+ a['ListType'] = _list = []
138
+ a['NoneType'] = None
139
+ a['ObjectType'] = object()
140
+ a['StringType'] = _str = str(1)
141
+ a['TupleType'] = _tuple = ()
142
+ a['TypeType'] = type
143
+ a['LongType'] = _int
144
+ a['UnicodeType'] = _str
145
+ # built-in constants (CH 4)
146
+ a['CopyrightType'] = copyright
147
+ # built-in types (CH 5)
148
+ a['ClassObjectType'] = _newclass # <type 'type'>
149
+ a['ClassInstanceType'] = _newclass() # <type 'class'>
150
+ a['SetType'] = _set = set()
151
+ a['FrozenSetType'] = frozenset()
152
+ # built-in exceptions (CH 6)
153
+ a['ExceptionType'] = _exception = _function2()[0]
154
+ # string services (CH 7)
155
+ a['SREPatternType'] = _srepattern = re.compile('')
156
+ # data types (CH 8)
157
+ a['ArrayType'] = array.array("f")
158
+ a['DequeType'] = collections.deque([0])
159
+ a['DefaultDictType'] = collections.defaultdict(_function, _dict)
160
+ a['TZInfoType'] = datetime.tzinfo()
161
+ a['DateTimeType'] = datetime.datetime.today()
162
+ a['CalendarType'] = calendar.Calendar()
163
+ # numeric and mathematical types (CH 9)
164
+ a['DecimalType'] = decimal.Decimal(1)
165
+ a['CountType'] = itertools.count(0)
166
+ # data compression and archiving (CH 12)
167
+ a['TarInfoType'] = tarfile.TarInfo()
168
+ # generic operating system services (CH 15)
169
+ a['LoggerType'] = _logger = logging.getLogger()
170
+ a['FormatterType'] = logging.Formatter() # pickle ok
171
+ a['FilterType'] = logging.Filter() # pickle ok
172
+ a['LogRecordType'] = logging.makeLogRecord(_dict) # pickle ok
173
+ a['OptionParserType'] = _oparser = optparse.OptionParser() # pickle ok
174
+ a['OptionGroupType'] = optparse.OptionGroup(_oparser,"foo") # pickle ok
175
+ a['OptionType'] = optparse.Option('--foo') # pickle ok
176
+ if HAS_CTYPES:
177
+ z = x if IS_PYPY else a
178
+ z['CCharType'] = _cchar = ctypes.c_char()
179
+ z['CWCharType'] = ctypes.c_wchar() # fail == 2.6
180
+ z['CByteType'] = ctypes.c_byte()
181
+ z['CUByteType'] = ctypes.c_ubyte()
182
+ z['CShortType'] = ctypes.c_short()
183
+ z['CUShortType'] = ctypes.c_ushort()
184
+ z['CIntType'] = ctypes.c_int()
185
+ z['CUIntType'] = ctypes.c_uint()
186
+ z['CLongType'] = ctypes.c_long()
187
+ z['CULongType'] = ctypes.c_ulong()
188
+ z['CLongLongType'] = ctypes.c_longlong()
189
+ z['CULongLongType'] = ctypes.c_ulonglong()
190
+ z['CFloatType'] = ctypes.c_float()
191
+ z['CDoubleType'] = ctypes.c_double()
192
+ z['CSizeTType'] = ctypes.c_size_t()
193
+ del z
194
+ a['CLibraryLoaderType'] = ctypes.cdll
195
+ a['StructureType'] = _Struct
196
+ # if not IS_PYPY:
197
+ # a['BigEndianStructureType'] = ctypes.BigEndianStructure()
198
+ #NOTE: also LittleEndianStructureType and UnionType... abstract classes
199
+ #NOTE: remember for ctypesobj.contents creates a new python object
200
+ #NOTE: ctypes.c_int._objects is memberdescriptor for object's __dict__
201
+ #NOTE: base class of all ctypes data types is non-public _CData
202
+
203
+ import fractions
204
+ import io
205
+ from io import StringIO as TextIO
206
+ # built-in functions (CH 2)
207
+ a['ByteArrayType'] = bytearray([1])
208
+ # numeric and mathematical types (CH 9)
209
+ a['FractionType'] = fractions.Fraction()
210
+ a['NumberType'] = numbers.Number()
211
+ # generic operating system services (CH 15)
212
+ a['IOBaseType'] = io.IOBase()
213
+ a['RawIOBaseType'] = io.RawIOBase()
214
+ a['TextIOBaseType'] = io.TextIOBase()
215
+ a['BufferedIOBaseType'] = io.BufferedIOBase()
216
+ a['UnicodeIOType'] = TextIO() # the new StringIO
217
+ a['LoggerAdapterType'] = logging.LoggerAdapter(_logger,_dict) # pickle ok
218
+ if HAS_CTYPES:
219
+ z = x if IS_PYPY else a
220
+ z['CBoolType'] = ctypes.c_bool(1)
221
+ z['CLongDoubleType'] = ctypes.c_longdouble()
222
+ del z
223
+ import argparse
224
+ # data types (CH 8)
225
+ a['OrderedDictType'] = collections.OrderedDict(_dict)
226
+ a['CounterType'] = collections.Counter(_dict)
227
+ if HAS_CTYPES:
228
+ z = x if IS_PYPY else a
229
+ z['CSSizeTType'] = ctypes.c_ssize_t()
230
+ del z
231
+ # generic operating system services (CH 15)
232
+ a['NullHandlerType'] = logging.NullHandler() # pickle ok # new 2.7
233
+ a['ArgParseFileType'] = argparse.FileType() # pickle ok
234
+
235
+ # -- pickle fails on all below here -----------------------------------------
236
+ # types module (part of CH 8)
237
+ a['CodeType'] = compile('','','exec')
238
+ a['DictProxyType'] = type.__dict__
239
+ a['DictProxyType2'] = _newclass.__dict__
240
+ a['EllipsisType'] = Ellipsis
241
+ a['ClosedFileType'] = open(os.devnull, 'wb', buffering=0).close()
242
+ a['GetSetDescriptorType'] = array.array.typecode
243
+ a['LambdaType'] = _lambda = lambda x: lambda y: x #XXX: works when not imported!
244
+ a['MemberDescriptorType'] = _newclass2.descriptor
245
+ if not IS_PYPY:
246
+ a['MemberDescriptorType2'] = datetime.timedelta.days
247
+ a['MethodType'] = _method = _class()._method #XXX: works when not imported!
248
+ a['ModuleType'] = datetime
249
+ a['NotImplementedType'] = NotImplemented
250
+ a['SliceType'] = slice(1)
251
+ a['UnboundMethodType'] = _class._method #XXX: works when not imported!
252
+ d['TextWrapperType'] = open(os.devnull, 'r') # same as mode='w','w+','r+'
253
+ d['BufferedRandomType'] = open(os.devnull, 'r+b') # same as mode='w+b'
254
+ d['BufferedReaderType'] = open(os.devnull, 'rb') # (default: buffering=-1)
255
+ d['BufferedWriterType'] = open(os.devnull, 'wb')
256
+ try: # oddities: deprecated
257
+ from _pyio import open as _open
258
+ d['PyTextWrapperType'] = _open(os.devnull, 'r', buffering=-1)
259
+ d['PyBufferedRandomType'] = _open(os.devnull, 'r+b', buffering=-1)
260
+ d['PyBufferedReaderType'] = _open(os.devnull, 'rb', buffering=-1)
261
+ d['PyBufferedWriterType'] = _open(os.devnull, 'wb', buffering=-1)
262
+ except ImportError:
263
+ pass
264
+ # other (concrete) object types
265
+ z = d if sys.hexversion < 0x30800a2 else a
266
+ z['CellType'] = (_lambda)(0).__closure__[0]
267
+ del z
268
+ a['XRangeType'] = _xrange = range(1)
269
+ a['MethodDescriptorType'] = type.__dict__['mro']
270
+ a['WrapperDescriptorType'] = type.__repr__
271
+ #a['WrapperDescriptorType2'] = type.__dict__['__module__']#XXX: GetSetDescriptor
272
+ a['ClassMethodDescriptorType'] = type.__dict__['__prepare__']
273
+ # built-in functions (CH 2)
274
+ _methodwrap = (1).__lt__
275
+ a['MethodWrapperType'] = _methodwrap
276
+ a['StaticMethodType'] = staticmethod(_method)
277
+ a['ClassMethodType'] = classmethod(_method)
278
+ a['PropertyType'] = property()
279
+ d['SuperType'] = super(Exception, _exception)
280
+ # string services (CH 7)
281
+ _in = _bytes
282
+ a['InputType'] = _cstrI = StringIO(_in)
283
+ a['OutputType'] = _cstrO = StringIO()
284
+ # data types (CH 8)
285
+ a['WeakKeyDictionaryType'] = weakref.WeakKeyDictionary()
286
+ a['WeakValueDictionaryType'] = weakref.WeakValueDictionary()
287
+ a['ReferenceType'] = weakref.ref(_instance)
288
+ a['DeadReferenceType'] = weakref.ref(_class())
289
+ a['ProxyType'] = weakref.proxy(_instance)
290
+ a['DeadProxyType'] = weakref.proxy(_class())
291
+ a['CallableProxyType'] = weakref.proxy(_instance2)
292
+ a['DeadCallableProxyType'] = weakref.proxy(_class2())
293
+ a['QueueType'] = Queue.Queue()
294
+ # numeric and mathematical types (CH 9)
295
+ d['PartialType'] = functools.partial(int,base=2)
296
+ a['IzipType'] = zip('0','1')
297
+ a['ChainType'] = itertools.chain('0','1')
298
+ d['ItemGetterType'] = operator.itemgetter(0)
299
+ d['AttrGetterType'] = operator.attrgetter('__repr__')
300
+ # file and directory access (CH 10)
301
+ _fileW = _cstrO
302
+ # data persistence (CH 11)
303
+ if HAS_ALL:
304
+ x['ConnectionType'] = _conn = sqlite3.connect(':memory:')
305
+ x['CursorType'] = _conn.cursor()
306
+ a['ShelveType'] = shelve.Shelf({})
307
+ # data compression and archiving (CH 12)
308
+ if HAS_ALL:
309
+ x['BZ2FileType'] = bz2.BZ2File(os.devnull)
310
+ x['BZ2CompressorType'] = bz2.BZ2Compressor()
311
+ x['BZ2DecompressorType'] = bz2.BZ2Decompressor()
312
+ #x['ZipFileType'] = _zip = zipfile.ZipFile(os.devnull,'w')
313
+ #_zip.write(_tempfile,'x') [causes annoying warning/error printed on import]
314
+ #a['ZipInfoType'] = _zip.getinfo('x')
315
+ a['TarFileType'] = tarfile.open(fileobj=_fileW,mode='w')
316
+ # file formats (CH 13)
317
+ x['DialectType'] = csv.get_dialect('excel')
318
+ if sys.hexversion < 0x30d00a1:
319
+ import xdrlib
320
+ a['PackerType'] = xdrlib.Packer()
321
+ # optional operating system services (CH 16)
322
+ a['LockType'] = threading.Lock()
323
+ a['RLockType'] = threading.RLock()
324
+ # generic operating system services (CH 15) # also closed/open and r/w/etc...
325
+ a['NamedLoggerType'] = _logger = logging.getLogger(__name__)
326
+ #a['FrozenModuleType'] = __hello__ #FIXME: prints "Hello world..."
327
+ # interprocess communication (CH 17)
328
+ x['SocketType'] = _socket = socket.socket()
329
+ x['SocketPairType'] = socket.socketpair()[0]
330
+ # python runtime services (CH 27)
331
+ a['GeneratorContextManagerType'] = contextlib.contextmanager(max)([1])
332
+
333
+ try: # ipython
334
+ __IPYTHON__ is True # is ipython
335
+ except NameError:
336
+ # built-in constants (CH 4)
337
+ a['QuitterType'] = quit
338
+ d['ExitType'] = a['QuitterType']
339
+ try: # numpy #FIXME: slow... 0.05 to 0.1 sec to import numpy
340
+ from numpy import ufunc as _numpy_ufunc
341
+ from numpy import array as _numpy_array
342
+ from numpy import int32 as _numpy_int32
343
+ a['NumpyUfuncType'] = _numpy_ufunc
344
+ a['NumpyArrayType'] = _numpy_array
345
+ a['NumpyInt32Type'] = _numpy_int32
346
+ except ImportError:
347
+ pass
348
+ # numeric and mathematical types (CH 9)
349
+ a['ProductType'] = itertools.product('0','1')
350
+ # generic operating system services (CH 15)
351
+ a['FileHandlerType'] = logging.FileHandler(os.devnull)
352
+ a['RotatingFileHandlerType'] = logging.handlers.RotatingFileHandler(os.devnull)
353
+ a['SocketHandlerType'] = logging.handlers.SocketHandler('localhost',514)
354
+ a['MemoryHandlerType'] = logging.handlers.MemoryHandler(1)
355
+ # data types (CH 8)
356
+ a['WeakSetType'] = weakref.WeakSet() # 2.7
357
+ # generic operating system services (CH 15) [errors when dill is imported]
358
+ #a['ArgumentParserType'] = _parser = argparse.ArgumentParser('PROG')
359
+ #a['NamespaceType'] = _parser.parse_args() # pickle ok
360
+ #a['SubParsersActionType'] = _parser.add_subparsers()
361
+ #a['MutuallyExclusiveGroupType'] = _parser.add_mutually_exclusive_group()
362
+ #a['ArgumentGroupType'] = _parser.add_argument_group()
363
+
364
+ # -- dill fails in some versions below here ---------------------------------
365
+ # types module (part of CH 8)
366
+ d['FileType'] = open(os.devnull, 'rb', buffering=0) # same 'wb','wb+','rb+'
367
+ # built-in functions (CH 2)
368
+ # Iterators:
369
+ a['ListIteratorType'] = iter(_list) # empty vs non-empty
370
+ a['SetIteratorType'] = iter(_set) #XXX: empty vs non-empty #FIXME: list_iterator
371
+ a['TupleIteratorType']= iter(_tuple) # empty vs non-empty
372
+ a['XRangeIteratorType'] = iter(_xrange) # empty vs non-empty
373
+ a["BytesIteratorType"] = iter(b'')
374
+ a["BytearrayIteratorType"] = iter(bytearray(b''))
375
+ z = x if IS_PYPY else a
376
+ z["CallableIteratorType"] = iter(iter, None)
377
+ del z
378
+ x["MemoryIteratorType"] = iter(memoryview(b''))
379
+ a["ListReverseiteratorType"] = reversed([])
380
+ X = a['OrderedDictType']
381
+ d["OdictKeysType"] = X.keys()
382
+ d["OdictValuesType"] = X.values()
383
+ d["OdictItemsType"] = X.items()
384
+ a["OdictIteratorType"] = iter(X.keys()) #FIXME: list_iterator
385
+ del X
386
+ #FIXME: list_iterator
387
+ a['DictionaryItemIteratorType'] = iter(type.__dict__.items())
388
+ a['DictionaryKeyIteratorType'] = iter(type.__dict__.keys())
389
+ a['DictionaryValueIteratorType'] = iter(type.__dict__.values())
390
+ if sys.hexversion >= 0x30800a0:
391
+ a["DictReversekeyiteratorType"] = reversed({}.keys())
392
+ a["DictReversevalueiteratorType"] = reversed({}.values())
393
+ a["DictReverseitemiteratorType"] = reversed({}.items())
394
+
395
+ try:
396
+ import symtable
397
+ #FIXME: fails to pickle
398
+ x["SymtableEntryType"] = symtable.symtable("", "string", "exec")._table
399
+ except ImportError:
400
+ pass
401
+
402
+ if sys.hexversion >= 0x30a00a0 and not IS_PYPY:
403
+ x['LineIteratorType'] = compile('3', '', 'eval').co_lines()
404
+
405
+ if sys.hexversion >= 0x30b00b0:
406
+ from types import GenericAlias
407
+ d["GenericAliasIteratorType"] = iter(GenericAlias(list, (int,)))
408
+ x['PositionsIteratorType'] = compile('3', '', 'eval').co_positions()
409
+
410
+ # data types (CH 8)
411
+ a['PrettyPrinterType'] = pprint.PrettyPrinter()
412
+ # numeric and mathematical types (CH 9)
413
+ a['CycleType'] = itertools.cycle('0')
414
+ # file and directory access (CH 10)
415
+ a['TemporaryFileType'] = _tmpf
416
+ # data compression and archiving (CH 12)
417
+ x['GzipFileType'] = gzip.GzipFile(fileobj=_fileW)
418
+ # generic operating system services (CH 15)
419
+ a['StreamHandlerType'] = logging.StreamHandler()
420
+ # numeric and mathematical types (CH 9)
421
+ a['PermutationsType'] = itertools.permutations('0')
422
+ a['CombinationsType'] = itertools.combinations('0',1)
423
+ a['RepeatType'] = itertools.repeat(0)
424
+ a['CompressType'] = itertools.compress('0',[1])
425
+ #XXX: ...and etc
426
+
427
+ # -- dill fails on all below here -------------------------------------------
428
+ # types module (part of CH 8)
429
+ x['GeneratorType'] = _generator = _function(1) #XXX: priority
430
+ x['FrameType'] = _generator.gi_frame #XXX: inspect.currentframe()
431
+ x['TracebackType'] = _function2()[1] #(see: inspect.getouterframes,getframeinfo)
432
+ # other (concrete) object types
433
+ # (also: Capsule / CObject ?)
434
+ # built-in functions (CH 2)
435
+ # built-in types (CH 5)
436
+ # string services (CH 7)
437
+ x['StructType'] = struct.Struct('c')
438
+ x['CallableIteratorType'] = _srepattern.finditer('')
439
+ x['SREMatchType'] = _srepattern.match('')
440
+ x['SREScannerType'] = _srepattern.scanner('')
441
+ x['StreamReader'] = codecs.StreamReader(_cstrI) #XXX: ... and etc
442
+ # python object persistence (CH 11)
443
+ # x['DbShelveType'] = shelve.open('foo','n')#,protocol=2) #XXX: delete foo
444
+ if HAS_ALL:
445
+ z = a if IS_PYPY else x
446
+ z['DbmType'] = dbm.open(_tempfile,'n')
447
+ del z
448
+ # x['DbCursorType'] = _dbcursor = anydbm.open('foo','n') #XXX: delete foo
449
+ # x['DbType'] = _dbcursor.db
450
+ # data compression and archiving (CH 12)
451
+ x['ZlibCompressType'] = zlib.compressobj()
452
+ x['ZlibDecompressType'] = zlib.decompressobj()
453
+ # file formats (CH 13)
454
+ x['CSVReaderType'] = csv.reader(_cstrI)
455
+ x['CSVWriterType'] = csv.writer(_cstrO)
456
+ x['CSVDictReaderType'] = csv.DictReader(_cstrI)
457
+ x['CSVDictWriterType'] = csv.DictWriter(_cstrO,{})
458
+ # cryptographic services (CH 14)
459
+ x['HashType'] = hashlib.md5()
460
+ if (sys.hexversion < 0x30800a1):
461
+ x['HMACType'] = hmac.new(_in)
462
+ else:
463
+ x['HMACType'] = hmac.new(_in, digestmod='md5')
464
+ # generic operating system services (CH 15)
465
+ if HAS_CURSES: pass
466
+ #x['CursesWindowType'] = _curwin = curses.initscr() #FIXME: messes up tty
467
+ #x['CursesTextPadType'] = textpad.Textbox(_curwin)
468
+ #x['CursesPanelType'] = panel.new_panel(_curwin)
469
+ if HAS_CTYPES:
470
+ x['CCharPType'] = ctypes.c_char_p()
471
+ x['CWCharPType'] = ctypes.c_wchar_p()
472
+ x['CVoidPType'] = ctypes.c_void_p()
473
+ if sys.platform[:3] == 'win':
474
+ x['CDLLType'] = _cdll = ctypes.cdll.msvcrt
475
+ else:
476
+ x['CDLLType'] = _cdll = ctypes.CDLL(None)
477
+ if not IS_PYPY:
478
+ x['PyDLLType'] = _pydll = ctypes.pythonapi
479
+ x['FuncPtrType'] = _cdll._FuncPtr()
480
+ x['CCharArrayType'] = ctypes.create_string_buffer(1)
481
+ x['CWCharArrayType'] = ctypes.create_unicode_buffer(1)
482
+ x['CParamType'] = ctypes.byref(_cchar)
483
+ x['LPCCharType'] = ctypes.pointer(_cchar)
484
+ x['LPCCharObjType'] = _lpchar = ctypes.POINTER(ctypes.c_char)
485
+ x['NullPtrType'] = _lpchar()
486
+ x['NullPyObjectType'] = ctypes.py_object()
487
+ x['PyObjectType'] = ctypes.py_object(lambda :None)
488
+ z = a if IS_PYPY else x
489
+ z['FieldType'] = _field = _Struct._field
490
+ z['CFUNCTYPEType'] = _cfunc = ctypes.CFUNCTYPE(ctypes.c_char)
491
+ if sys.hexversion < 0x30c00b3:
492
+ x['CFunctionType'] = _cfunc(str)
493
+ del z
494
+ # numeric and mathematical types (CH 9)
495
+ a['MethodCallerType'] = operator.methodcaller('mro') # 2.6
496
+ # built-in types (CH 5)
497
+ x['MemoryType'] = memoryview(_in) # 2.7
498
+ x['MemoryType2'] = memoryview(bytearray(_in)) # 2.7
499
+ d['DictItemsType'] = _dict.items() # 2.7
500
+ d['DictKeysType'] = _dict.keys() # 2.7
501
+ d['DictValuesType'] = _dict.values() # 2.7
502
+ # generic operating system services (CH 15)
503
+ a['RawTextHelpFormatterType'] = argparse.RawTextHelpFormatter('PROG')
504
+ a['RawDescriptionHelpFormatterType'] = argparse.RawDescriptionHelpFormatter('PROG')
505
+ a['ArgDefaultsHelpFormatterType'] = argparse.ArgumentDefaultsHelpFormatter('PROG')
506
+ z = a if IS_PYPY else x
507
+ z['CmpKeyType'] = _cmpkey = functools.cmp_to_key(_methodwrap) # 2.7, >=3.2
508
+ z['CmpKeyObjType'] = _cmpkey('0') #2.7, >=3.2
509
+ del z
510
+ # oddities: removed, etc
511
+ x['BufferType'] = x['MemoryType']
512
+
513
+ from dill._dill import _testcapsule
514
+ if _testcapsule is not None:
515
+ d['PyCapsuleType'] = _testcapsule
516
+ del _testcapsule
517
+
518
+ if hasattr(dataclasses, '_HAS_DEFAULT_FACTORY'):
519
+ a['DataclassesHasDefaultFactoryType'] = dataclasses._HAS_DEFAULT_FACTORY
520
+
521
+ if hasattr(dataclasses, 'MISSING'):
522
+ a['DataclassesMissingType'] = dataclasses.MISSING
523
+
524
+ if hasattr(dataclasses, 'KW_ONLY'):
525
+ a['DataclassesKWOnlyType'] = dataclasses.KW_ONLY
526
+
527
+ if hasattr(dataclasses, '_FIELD_BASE'):
528
+ a['DataclassesFieldBaseType'] = dataclasses._FIELD
529
+
530
+ # -- cleanup ----------------------------------------------------------------
531
+ a.update(d) # registered also succeed
532
+ if sys.platform[:3] == 'win':
533
+ os.close(_filedescrip) # required on win32
534
+ os.remove(_tempfile)
535
+
536
+
537
+ # EOF
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/_shims.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Author: Anirudh Vegesana (avegesan@cs.stanford.edu)
5
+ # Copyright (c) 2021-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+ """
9
+ Provides shims for compatibility between versions of dill and Python.
10
+
11
+ Compatibility shims should be provided in this file. Here are two simple example
12
+ use cases.
13
+
14
+ Deprecation of constructor function:
15
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16
+ Assume that we were transitioning _import_module in _dill.py to
17
+ the builtin function importlib.import_module when present.
18
+
19
+ @move_to(_dill)
20
+ def _import_module(import_name):
21
+ ... # code already in _dill.py
22
+
23
+ _import_module = Getattr(importlib, 'import_module', Getattr(_dill, '_import_module', None))
24
+
25
+ The code will attempt to find import_module in the importlib module. If not
26
+ present, it will use the _import_module function in _dill.
27
+
28
+ Emulate new Python behavior in older Python versions:
29
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30
+ CellType.cell_contents behaves differently in Python 3.6 and 3.7. It is
31
+ read-only in Python 3.6 and writable and deletable in 3.7.
32
+
33
+ if _dill.OLD37 and _dill.HAS_CTYPES and ...:
34
+ @move_to(_dill)
35
+ def _setattr(object, name, value):
36
+ if type(object) is _dill.CellType and name == 'cell_contents':
37
+ _PyCell_Set.argtypes = (ctypes.py_object, ctypes.py_object)
38
+ _PyCell_Set(object, value)
39
+ else:
40
+ setattr(object, name, value)
41
+ ... # more cases below
42
+
43
+ _setattr = Getattr(_dill, '_setattr', setattr)
44
+
45
+ _dill._setattr will be used when present to emulate Python 3.7 functionality in
46
+ older versions of Python while defaulting to the standard setattr in 3.7+.
47
+
48
+ See this PR for the discussion that lead to this system:
49
+ https://github.com/uqfoundation/dill/pull/443
50
+ """
51
+
52
+ import inspect
53
+ import sys
54
+
55
+ _dill = sys.modules['dill._dill']
56
+
57
+
58
+ class Reduce(object):
59
+ """
60
+ Reduce objects are wrappers used for compatibility enforcement during
61
+ unpickle-time. They should only be used in calls to pickler.save and
62
+ other Reduce objects. They are only evaluated within unpickler.load.
63
+
64
+ Pickling a Reduce object makes the two implementations equivalent:
65
+
66
+ pickler.save(Reduce(*reduction))
67
+
68
+ pickler.save_reduce(*reduction, obj=reduction)
69
+ """
70
+ __slots__ = ['reduction']
71
+ def __new__(cls, *reduction, **kwargs):
72
+ """
73
+ Args:
74
+ *reduction: a tuple that matches the format given here:
75
+ https://docs.python.org/3/library/pickle.html#object.__reduce__
76
+ is_callable: a bool to indicate that the object created by
77
+ unpickling `reduction` is callable. If true, the current Reduce
78
+ is allowed to be used as the function in further save_reduce calls
79
+ or Reduce objects.
80
+ """
81
+ is_callable = kwargs.get('is_callable', False) # Pleases Py2. Can be removed later
82
+ if is_callable:
83
+ self = object.__new__(_CallableReduce)
84
+ else:
85
+ self = object.__new__(Reduce)
86
+ self.reduction = reduction
87
+ return self
88
+ def __repr__(self):
89
+ return 'Reduce%s' % (self.reduction,)
90
+ def __copy__(self):
91
+ return self # pragma: no cover
92
+ def __deepcopy__(self, memo):
93
+ return self # pragma: no cover
94
+ def __reduce__(self):
95
+ return self.reduction
96
+ def __reduce_ex__(self, protocol):
97
+ return self.__reduce__()
98
+
99
+ class _CallableReduce(Reduce):
100
+ # A version of Reduce for functions. Used to trick pickler.save_reduce into
101
+ # thinking that Reduce objects of functions are themselves meaningful functions.
102
+ def __call__(self, *args, **kwargs):
103
+ reduction = self.__reduce__()
104
+ func = reduction[0]
105
+ f_args = reduction[1]
106
+ obj = func(*f_args)
107
+ return obj(*args, **kwargs)
108
+
109
+ __NO_DEFAULT = _dill.Sentinel('Getattr.NO_DEFAULT')
110
+
111
+ def Getattr(object, name, default=__NO_DEFAULT):
112
+ """
113
+ A Reduce object that represents the getattr operation. When unpickled, the
114
+ Getattr will access an attribute 'name' of 'object' and return the value
115
+ stored there. If the attribute doesn't exist, the default value will be
116
+ returned if present.
117
+
118
+ The following statements are equivalent:
119
+
120
+ Getattr(collections, 'OrderedDict')
121
+ Getattr(collections, 'spam', None)
122
+ Getattr(*args)
123
+
124
+ Reduce(getattr, (collections, 'OrderedDict'))
125
+ Reduce(getattr, (collections, 'spam', None))
126
+ Reduce(getattr, args)
127
+
128
+ During unpickling, the first two will result in collections.OrderedDict and
129
+ None respectively because the first attribute exists and the second one does
130
+ not, forcing it to use the default value given in the third argument.
131
+ """
132
+
133
+ if default is Getattr.NO_DEFAULT:
134
+ reduction = (getattr, (object, name))
135
+ else:
136
+ reduction = (getattr, (object, name, default))
137
+
138
+ return Reduce(*reduction, is_callable=callable(default))
139
+
140
+ Getattr.NO_DEFAULT = __NO_DEFAULT
141
+ del __NO_DEFAULT
142
+
143
+ def move_to(module, name=None):
144
+ def decorator(func):
145
+ if name is None:
146
+ fname = func.__name__
147
+ else:
148
+ fname = name
149
+ module.__dict__[fname] = func
150
+ func.__module__ = module.__name__
151
+ return func
152
+ return decorator
153
+
154
+ def register_shim(name, default):
155
+ """
156
+ A easier to understand and more compact way of "softly" defining a function.
157
+ These two pieces of code are equivalent:
158
+
159
+ if _dill.OLD3X:
160
+ def _create_class():
161
+ ...
162
+ _create_class = register_shim('_create_class', types.new_class)
163
+
164
+ if _dill.OLD3X:
165
+ @move_to(_dill)
166
+ def _create_class():
167
+ ...
168
+ _create_class = Getattr(_dill, '_create_class', types.new_class)
169
+
170
+ Intuitively, it creates a function or object in the versions of dill/python
171
+ that require special reimplementations, and use a core library or default
172
+ implementation if that function or object does not exist.
173
+ """
174
+ func = globals().get(name)
175
+ if func is not None:
176
+ _dill.__dict__[name] = func
177
+ func.__module__ = _dill.__name__
178
+
179
+ if default is Getattr.NO_DEFAULT:
180
+ reduction = (getattr, (_dill, name))
181
+ else:
182
+ reduction = (getattr, (_dill, name, default))
183
+
184
+ return Reduce(*reduction, is_callable=callable(default))
185
+
186
+ ######################
187
+ ## Compatibility Shims are defined below
188
+ ######################
189
+
190
+ _CELL_EMPTY = register_shim('_CELL_EMPTY', None)
191
+
192
+ _setattr = register_shim('_setattr', setattr)
193
+ _delattr = register_shim('_delattr', delattr)
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/detect.py ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2016 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+ """
9
+ Methods for detecting objects leading to pickling failures.
10
+ """
11
+
12
+ import dis
13
+ from inspect import ismethod, isfunction, istraceback, isframe, iscode
14
+
15
+ from .pointers import parent, reference, at, parents, children
16
+ from .logger import trace
17
+
18
+ __all__ = ['baditems','badobjects','badtypes','code','errors','freevars',
19
+ 'getmodule','globalvars','nestedcode','nestedglobals','outermost',
20
+ 'referredglobals','referrednested','trace','varnames']
21
+
22
+ def getmodule(object, _filename=None, force=False):
23
+ """get the module of the object"""
24
+ from inspect import getmodule as getmod
25
+ module = getmod(object, _filename)
26
+ if module or not force: return module
27
+ import builtins
28
+ from .source import getname
29
+ name = getname(object, force=True)
30
+ return builtins if name in vars(builtins).keys() else None
31
+
32
+ def outermost(func): # is analogous to getsource(func,enclosing=True)
33
+ """get outermost enclosing object (i.e. the outer function in a closure)
34
+
35
+ NOTE: this is the object-equivalent of getsource(func, enclosing=True)
36
+ """
37
+ if ismethod(func):
38
+ _globals = func.__func__.__globals__ or {}
39
+ elif isfunction(func):
40
+ _globals = func.__globals__ or {}
41
+ else:
42
+ return #XXX: or raise? no matches
43
+ _globals = _globals.items()
44
+ # get the enclosing source
45
+ from .source import getsourcelines
46
+ try: lines,lnum = getsourcelines(func, enclosing=True)
47
+ except Exception: #TypeError, IOError
48
+ lines,lnum = [],None
49
+ code = ''.join(lines)
50
+ # get all possible names,objects that are named in the enclosing source
51
+ _locals = ((name,obj) for (name,obj) in _globals if name in code)
52
+ # now only save the objects that generate the enclosing block
53
+ for name,obj in _locals: #XXX: don't really need 'name'
54
+ try:
55
+ if getsourcelines(obj) == (lines,lnum): return obj
56
+ except Exception: #TypeError, IOError
57
+ pass
58
+ return #XXX: or raise? no matches
59
+
60
+ def nestedcode(func, recurse=True): #XXX: or return dict of {co_name: co} ?
61
+ """get the code objects for any nested functions (e.g. in a closure)"""
62
+ func = code(func)
63
+ if not iscode(func): return [] #XXX: or raise? no matches
64
+ nested = set()
65
+ for co in func.co_consts:
66
+ if co is None: continue
67
+ co = code(co)
68
+ if co:
69
+ nested.add(co)
70
+ if recurse: nested |= set(nestedcode(co, recurse=True))
71
+ return list(nested)
72
+
73
+ def code(func):
74
+ """get the code object for the given function or method
75
+
76
+ NOTE: use dill.source.getsource(CODEOBJ) to get the source code
77
+ """
78
+ if ismethod(func): func = func.__func__
79
+ if isfunction(func): func = func.__code__
80
+ if istraceback(func): func = func.tb_frame
81
+ if isframe(func): func = func.f_code
82
+ if iscode(func): return func
83
+ return
84
+
85
+ #XXX: ugly: parse dis.dis for name after "<code object" in line and in globals?
86
+ def referrednested(func, recurse=True): #XXX: return dict of {__name__: obj} ?
87
+ """get functions defined inside of func (e.g. inner functions in a closure)
88
+
89
+ NOTE: results may differ if the function has been executed or not.
90
+ If len(nestedcode(func)) > len(referrednested(func)), try calling func().
91
+ If possible, python builds code objects, but delays building functions
92
+ until func() is called.
93
+ """
94
+ import gc
95
+ funcs = set()
96
+ # get the code objects, and try to track down by referrence
97
+ for co in nestedcode(func, recurse):
98
+ # look for function objects that refer to the code object
99
+ for obj in gc.get_referrers(co):
100
+ # get methods
101
+ _ = getattr(obj, '__func__', None) # ismethod
102
+ if getattr(_, '__code__', None) is co: funcs.add(obj)
103
+ # get functions
104
+ elif getattr(obj, '__code__', None) is co: funcs.add(obj)
105
+ # get frame objects
106
+ elif getattr(obj, 'f_code', None) is co: funcs.add(obj)
107
+ # get code objects
108
+ elif hasattr(obj, 'co_code') and obj is co: funcs.add(obj)
109
+ # frameobjs => func.__code__.co_varnames not in func.__code__.co_cellvars
110
+ # funcobjs => func.__code__.co_cellvars not in func.__code__.co_varnames
111
+ # frameobjs are not found, however funcobjs are...
112
+ # (see: test_mixins.quad ... and test_mixins.wtf)
113
+ # after execution, code objects get compiled, and then may be found by gc
114
+ return list(funcs)
115
+
116
+
117
+ def freevars(func):
118
+ """get objects defined in enclosing code that are referred to by func
119
+
120
+ returns a dict of {name:object}"""
121
+ if ismethod(func): func = func.__func__
122
+ if isfunction(func):
123
+ closures = func.__closure__ or ()
124
+ func = func.__code__.co_freevars # get freevars
125
+ else:
126
+ return {}
127
+
128
+ def get_cell_contents():
129
+ for name, c in zip(func, closures):
130
+ try:
131
+ cell_contents = c.cell_contents
132
+ except ValueError: # cell is empty
133
+ continue
134
+ yield name, c.cell_contents
135
+
136
+ return dict(get_cell_contents())
137
+
138
+ # thanks to Davies Liu for recursion of globals
139
+ def nestedglobals(func, recurse=True):
140
+ """get the names of any globals found within func"""
141
+ func = code(func)
142
+ if func is None: return list()
143
+ import sys
144
+ from .temp import capture
145
+ CAN_NULL = sys.hexversion >= 0x30b00a7 # NULL may be prepended >= 3.11a7
146
+ names = set()
147
+ with capture('stdout') as out:
148
+ dis.dis(func) #XXX: dis.dis(None) disassembles last traceback
149
+ for line in out.getvalue().splitlines():
150
+ if '_GLOBAL' in line:
151
+ name = line.split('(')[-1].split(')')[0]
152
+ if CAN_NULL:
153
+ names.add(name.replace('NULL + ', '').replace(' + NULL', ''))
154
+ else:
155
+ names.add(name)
156
+ for co in getattr(func, 'co_consts', tuple()):
157
+ if co and recurse and iscode(co):
158
+ names.update(nestedglobals(co, recurse=True))
159
+ return list(names)
160
+
161
+ def referredglobals(func, recurse=True, builtin=False):
162
+ """get the names of objects in the global scope referred to by func"""
163
+ return globalvars(func, recurse, builtin).keys()
164
+
165
+ def globalvars(func, recurse=True, builtin=False):
166
+ """get objects defined in global scope that are referred to by func
167
+
168
+ return a dict of {name:object}"""
169
+ if ismethod(func): func = func.__func__
170
+ if isfunction(func):
171
+ globs = vars(getmodule(sum)).copy() if builtin else {}
172
+ # get references from within closure
173
+ orig_func, func = func, set()
174
+ for obj in orig_func.__closure__ or {}:
175
+ try:
176
+ cell_contents = obj.cell_contents
177
+ except ValueError: # cell is empty
178
+ pass
179
+ else:
180
+ _vars = globalvars(cell_contents, recurse, builtin) or {}
181
+ func.update(_vars) #XXX: (above) be wary of infinte recursion?
182
+ globs.update(_vars)
183
+ # get globals
184
+ globs.update(orig_func.__globals__ or {})
185
+ # get names of references
186
+ if not recurse:
187
+ func.update(orig_func.__code__.co_names)
188
+ else:
189
+ func.update(nestedglobals(orig_func.__code__))
190
+ # find globals for all entries of func
191
+ for key in func.copy(): #XXX: unnecessary...?
192
+ nested_func = globs.get(key)
193
+ if nested_func is orig_func:
194
+ #func.remove(key) if key in func else None
195
+ continue #XXX: globalvars(func, False)?
196
+ func.update(globalvars(nested_func, True, builtin))
197
+ elif iscode(func):
198
+ globs = vars(getmodule(sum)).copy() if builtin else {}
199
+ #globs.update(globals())
200
+ if not recurse:
201
+ func = func.co_names # get names
202
+ else:
203
+ orig_func = func.co_name # to stop infinite recursion
204
+ func = set(nestedglobals(func))
205
+ # find globals for all entries of func
206
+ for key in func.copy(): #XXX: unnecessary...?
207
+ if key is orig_func:
208
+ #func.remove(key) if key in func else None
209
+ continue #XXX: globalvars(func, False)?
210
+ nested_func = globs.get(key)
211
+ func.update(globalvars(nested_func, True, builtin))
212
+ else:
213
+ return {}
214
+ #NOTE: if name not in __globals__, then we skip it...
215
+ return dict((name,globs[name]) for name in func if name in globs)
216
+
217
+
218
+ def varnames(func):
219
+ """get names of variables defined by func
220
+
221
+ returns a tuple (local vars, local vars referrenced by nested functions)"""
222
+ func = code(func)
223
+ if not iscode(func):
224
+ return () #XXX: better ((),())? or None?
225
+ return func.co_varnames, func.co_cellvars
226
+
227
+
228
+ def baditems(obj, exact=False, safe=False): #XXX: obj=globals() ?
229
+ """get items in object that fail to pickle"""
230
+ if not hasattr(obj,'__iter__'): # is not iterable
231
+ return [j for j in (badobjects(obj,0,exact,safe),) if j is not None]
232
+ obj = obj.values() if getattr(obj,'values',None) else obj
233
+ _obj = [] # can't use a set, as items may be unhashable
234
+ [_obj.append(badobjects(i,0,exact,safe)) for i in obj if i not in _obj]
235
+ return [j for j in _obj if j is not None]
236
+
237
+
238
+ def badobjects(obj, depth=0, exact=False, safe=False):
239
+ """get objects that fail to pickle"""
240
+ from dill import pickles
241
+ if not depth:
242
+ if pickles(obj,exact,safe): return None
243
+ return obj
244
+ return dict(((attr, badobjects(getattr(obj,attr),depth-1,exact,safe)) \
245
+ for attr in dir(obj) if not pickles(getattr(obj,attr),exact,safe)))
246
+
247
+ def badtypes(obj, depth=0, exact=False, safe=False):
248
+ """get types for objects that fail to pickle"""
249
+ from dill import pickles
250
+ if not depth:
251
+ if pickles(obj,exact,safe): return None
252
+ return type(obj)
253
+ return dict(((attr, badtypes(getattr(obj,attr),depth-1,exact,safe)) \
254
+ for attr in dir(obj) if not pickles(getattr(obj,attr),exact,safe)))
255
+
256
+ def errors(obj, depth=0, exact=False, safe=False):
257
+ """get errors for objects that fail to pickle"""
258
+ from dill import pickles, copy
259
+ if not depth:
260
+ try:
261
+ pik = copy(obj)
262
+ if exact:
263
+ assert pik == obj, \
264
+ "Unpickling produces %s instead of %s" % (pik,obj)
265
+ assert type(pik) == type(obj), \
266
+ "Unpickling produces %s instead of %s" % (type(pik),type(obj))
267
+ return None
268
+ except Exception:
269
+ import sys
270
+ return sys.exc_info()[1]
271
+ _dict = {}
272
+ for attr in dir(obj):
273
+ try:
274
+ _attr = getattr(obj,attr)
275
+ except Exception:
276
+ import sys
277
+ _dict[attr] = sys.exc_info()[1]
278
+ continue
279
+ if not pickles(_attr,exact,safe):
280
+ _dict[attr] = errors(_attr,depth-1,exact,safe)
281
+ return _dict
282
+
283
+
284
+ # EOF
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/logger.py ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # Author: Leonardo Gama (@leogama)
5
+ # Copyright (c) 2022-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+ """
9
+ Logging utilities for dill.
10
+
11
+ The 'logger' object is dill's top-level logger.
12
+
13
+ The 'adapter' object wraps the logger and implements a 'trace()' method that
14
+ generates a detailed tree-style trace for the pickling call at log level INFO.
15
+
16
+ The 'trace()' function sets and resets dill's logger log level, enabling and
17
+ disabling the pickling trace.
18
+
19
+ The trace shows a tree structure depicting the depth of each object serialized
20
+ *with dill save functions*, but not the ones that use save functions from
21
+ 'pickle._Pickler.dispatch'. If the information is available, it also displays
22
+ the size in bytes that the object contributed to the pickle stream (including
23
+ its child objects). Sample trace output:
24
+
25
+ >>> import dill, dill.tests
26
+ >>> dill.detect.trace(True)
27
+ >>> dill.dump_session(main=dill.tests)
28
+ ┬ M1: <module 'dill.tests' from '.../dill/tests/__init__.py'>
29
+ ├┬ F2: <function _import_module at 0x7f0d2dce1b80>
30
+ │└ # F2 [32 B]
31
+ ├┬ D2: <dict object at 0x7f0d2e98a540>
32
+ │├┬ T4: <class '_frozen_importlib.ModuleSpec'>
33
+ ││└ # T4 [35 B]
34
+ │├┬ D2: <dict object at 0x7f0d2ef0e8c0>
35
+ ││├┬ T4: <class '_frozen_importlib_external.SourceFileLoader'>
36
+ │││└ # T4 [50 B]
37
+ ││├┬ D2: <dict object at 0x7f0d2e988a40>
38
+ │││└ # D2 [84 B]
39
+ ││└ # D2 [413 B]
40
+ │└ # D2 [763 B]
41
+ └ # M1 [813 B]
42
+ """
43
+
44
+ __all__ = ['adapter', 'logger', 'trace']
45
+
46
+ import codecs
47
+ import contextlib
48
+ import locale
49
+ import logging
50
+ import math
51
+ import os
52
+ from functools import partial
53
+ from typing import TextIO, Union
54
+
55
+ import dill
56
+
57
+ # Tree drawing characters: Unicode to ASCII map.
58
+ ASCII_MAP = str.maketrans({"│": "|", "├": "|", "┬": "+", "└": "`"})
59
+
60
+ ## Notes about the design choices ##
61
+
62
+ # Here is some domumentation of the Standard Library's logging internals that
63
+ # can't be found completely in the official documentation. dill's logger is
64
+ # obtained by calling logging.getLogger('dill') and therefore is an instance of
65
+ # logging.getLoggerClass() at the call time. As this is controlled by the user,
66
+ # in order to add some functionality to it it's necessary to use a LoggerAdapter
67
+ # to wrap it, overriding some of the adapter's methods and creating new ones.
68
+ #
69
+ # Basic calling sequence
70
+ # ======================
71
+ #
72
+ # Python's logging functionality can be conceptually divided into five steps:
73
+ # 0. Check logging level -> abort if call level is greater than logger level
74
+ # 1. Gather information -> construct a LogRecord from passed arguments and context
75
+ # 2. Filter (optional) -> discard message if the record matches a filter
76
+ # 3. Format -> format message with args, then format output string with message plus record
77
+ # 4. Handle -> write the formatted string to output as defined in the handler
78
+ #
79
+ # dill.logging.logger.log -> # or logger.info, etc.
80
+ # Logger.log -> \
81
+ # Logger._log -> }- accept 'extra' parameter for custom record entries
82
+ # Logger.makeRecord -> /
83
+ # LogRecord.__init__
84
+ # Logger.handle ->
85
+ # Logger.callHandlers ->
86
+ # Handler.handle ->
87
+ # Filterer.filter ->
88
+ # Filter.filter
89
+ # StreamHandler.emit ->
90
+ # Handler.format ->
91
+ # Formatter.format ->
92
+ # LogRecord.getMessage # does: record.message = msg % args
93
+ # Formatter.formatMessage ->
94
+ # PercentStyle.format # does: self._fmt % vars(record)
95
+ #
96
+ # NOTE: All methods from the second line on are from logging.__init__.py
97
+
98
+ class TraceAdapter(logging.LoggerAdapter):
99
+ """
100
+ Tracks object tree depth and calculates pickled object size.
101
+
102
+ A single instance of this wraps the module's logger, as the logging API
103
+ doesn't allow setting it directly with a custom Logger subclass. The added
104
+ 'trace()' method receives a pickle instance as the first argument and
105
+ creates extra values to be added in the LogRecord from it, then calls
106
+ 'info()'.
107
+
108
+ Usage of logger with 'trace()' method:
109
+
110
+ >>> from dill.logger import adapter as logger #NOTE: not dill.logger.logger
111
+ >>> ...
112
+ >>> def save_atype(pickler, obj):
113
+ >>> logger.trace(pickler, "Message with %s and %r etc. placeholders", 'text', obj)
114
+ >>> ...
115
+ """
116
+ def __init__(self, logger):
117
+ self.logger = logger
118
+ def addHandler(self, handler):
119
+ formatter = TraceFormatter("%(prefix)s%(message)s%(suffix)s", handler=handler)
120
+ handler.setFormatter(formatter)
121
+ self.logger.addHandler(handler)
122
+ def removeHandler(self, handler):
123
+ self.logger.removeHandler(handler)
124
+ def process(self, msg, kwargs):
125
+ # A no-op override, as we don't have self.extra.
126
+ return msg, kwargs
127
+ def trace_setup(self, pickler):
128
+ # Called by Pickler.dump().
129
+ if not dill._dill.is_dill(pickler, child=False):
130
+ return
131
+ if self.isEnabledFor(logging.INFO):
132
+ pickler._trace_depth = 1
133
+ pickler._size_stack = []
134
+ else:
135
+ pickler._trace_depth = None
136
+ def trace(self, pickler, msg, *args, **kwargs):
137
+ if not hasattr(pickler, '_trace_depth'):
138
+ logger.info(msg, *args, **kwargs)
139
+ return
140
+ if pickler._trace_depth is None:
141
+ return
142
+ extra = kwargs.get('extra', {})
143
+ pushed_obj = msg.startswith('#')
144
+ size = None
145
+ try:
146
+ # Streams are not required to be tellable.
147
+ size = pickler._file.tell()
148
+ frame = pickler.framer.current_frame
149
+ try:
150
+ size += frame.tell()
151
+ except AttributeError:
152
+ # PyPy may use a BytesBuilder as frame
153
+ size += len(frame)
154
+ except (AttributeError, TypeError):
155
+ pass
156
+ if size is not None:
157
+ if not pushed_obj:
158
+ pickler._size_stack.append(size)
159
+ else:
160
+ size -= pickler._size_stack.pop()
161
+ extra['size'] = size
162
+ if pushed_obj:
163
+ pickler._trace_depth -= 1
164
+ extra['depth'] = pickler._trace_depth
165
+ kwargs['extra'] = extra
166
+ self.info(msg, *args, **kwargs)
167
+ if not pushed_obj:
168
+ pickler._trace_depth += 1
169
+
170
+ class TraceFormatter(logging.Formatter):
171
+ """
172
+ Generates message prefix and suffix from record.
173
+
174
+ This Formatter adds prefix and suffix strings to the log message in trace
175
+ mode (an also provides empty string defaults for normal logs).
176
+ """
177
+ def __init__(self, *args, handler=None, **kwargs):
178
+ super().__init__(*args, **kwargs)
179
+ try:
180
+ encoding = handler.stream.encoding
181
+ if encoding is None:
182
+ raise AttributeError
183
+ except AttributeError:
184
+ encoding = locale.getpreferredencoding()
185
+ try:
186
+ encoding = codecs.lookup(encoding).name
187
+ except LookupError:
188
+ self.is_utf8 = False
189
+ else:
190
+ self.is_utf8 = (encoding == codecs.lookup('utf-8').name)
191
+ def format(self, record):
192
+ fields = {'prefix': "", 'suffix': ""}
193
+ if getattr(record, 'depth', 0) > 0:
194
+ if record.msg.startswith("#"):
195
+ prefix = (record.depth - 1)*"│" + "└"
196
+ elif record.depth == 1:
197
+ prefix = "┬"
198
+ else:
199
+ prefix = (record.depth - 2)*"│" + "├┬"
200
+ if not self.is_utf8:
201
+ prefix = prefix.translate(ASCII_MAP) + "-"
202
+ fields['prefix'] = prefix + " "
203
+ if hasattr(record, 'size') and record.size is not None and record.size >= 1:
204
+ # Show object size in human-readable form.
205
+ power = int(math.log(record.size, 2)) // 10
206
+ size = record.size >> power*10
207
+ fields['suffix'] = " [%d %sB]" % (size, "KMGTP"[power] + "i" if power else "")
208
+ vars(record).update(fields)
209
+ return super().format(record)
210
+
211
+ logger = logging.getLogger('dill')
212
+ logger.propagate = False
213
+ adapter = TraceAdapter(logger)
214
+ stderr_handler = logging._StderrHandler()
215
+ adapter.addHandler(stderr_handler)
216
+
217
+ def trace(arg: Union[bool, TextIO, str, os.PathLike] = None, *, mode: str = 'a') -> None:
218
+ """print a trace through the stack when pickling; useful for debugging
219
+
220
+ With a single boolean argument, enable or disable the tracing.
221
+
222
+ Example usage:
223
+
224
+ >>> import dill
225
+ >>> dill.detect.trace(True)
226
+ >>> dill.dump_session()
227
+
228
+ Alternatively, ``trace()`` can be used as a context manager. With no
229
+ arguments, it just takes care of restoring the tracing state on exit.
230
+ Either a file handle, or a file name and (optionally) a file mode may be
231
+ specitfied to redirect the tracing output in the ``with`` block context. A
232
+ log function is yielded by the manager so the user can write extra
233
+ information to the file.
234
+
235
+ Example usage:
236
+
237
+ >>> from dill import detect
238
+ >>> D = {'a': 42, 'b': {'x': None}}
239
+ >>> with detect.trace():
240
+ >>> dumps(D)
241
+ ┬ D2: <dict object at 0x7f2721804800>
242
+ ├┬ D2: <dict object at 0x7f27217f5c40>
243
+ │└ # D2 [8 B]
244
+ └ # D2 [22 B]
245
+ >>> squared = lambda x: x**2
246
+ >>> with detect.trace('output.txt', mode='w') as log:
247
+ >>> log("> D = %r", D)
248
+ >>> dumps(D)
249
+ >>> log("> squared = %r", squared)
250
+ >>> dumps(squared)
251
+
252
+ Arguments:
253
+ arg: a boolean value, or an optional file-like or path-like object for the context manager
254
+ mode: mode string for ``open()`` if a file name is passed as the first argument
255
+ """
256
+ if not isinstance(arg, bool):
257
+ return TraceManager(file=arg, mode=mode)
258
+ logger.setLevel(logging.INFO if arg else logging.WARNING)
259
+
260
+ class TraceManager(contextlib.AbstractContextManager):
261
+ """context manager version of trace(); can redirect the trace to a file"""
262
+ def __init__(self, file, mode):
263
+ self.file = file
264
+ self.mode = mode
265
+ self.redirect = file is not None
266
+ self.file_is_stream = hasattr(file, 'write')
267
+ def __enter__(self):
268
+ if self.redirect:
269
+ stderr_handler.flush()
270
+ if self.file_is_stream:
271
+ self.handler = logging.StreamHandler(self.file)
272
+ else:
273
+ self.handler = logging.FileHandler(self.file, self.mode)
274
+ adapter.removeHandler(stderr_handler)
275
+ adapter.addHandler(self.handler)
276
+ self.old_level = adapter.getEffectiveLevel()
277
+ adapter.setLevel(logging.INFO)
278
+ return adapter.info
279
+ def __exit__(self, *exc_info):
280
+ adapter.setLevel(self.old_level)
281
+ if self.redirect:
282
+ adapter.removeHandler(self.handler)
283
+ adapter.addHandler(stderr_handler)
284
+ if not self.file_is_stream:
285
+ self.handler.close()
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/objtypes.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2016 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+ """
9
+ all Python Standard Library object types (currently: CH 1-15 @ 2.7)
10
+ and some other common object types (i.e. numpy.ndarray)
11
+
12
+ to load more objects and types, use dill.load_types()
13
+ """
14
+
15
+ # non-local import of dill.objects
16
+ from dill import objects
17
+ for _type in objects.keys():
18
+ exec("%s = type(objects['%s'])" % (_type,_type))
19
+
20
+ del objects
21
+ try:
22
+ del _type
23
+ except NameError:
24
+ pass
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/pointers.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2016 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+
9
+ __all__ = ['parent', 'reference', 'at', 'parents', 'children']
10
+
11
+ import gc
12
+ import sys
13
+
14
+ from ._dill import _proxy_helper as reference
15
+ from ._dill import _locate_object as at
16
+
17
+ def parent(obj, objtype, ignore=()):
18
+ """
19
+ >>> listiter = iter([4,5,6,7])
20
+ >>> obj = parent(listiter, list)
21
+ >>> obj == [4,5,6,7] # actually 'is', but don't have handle any longer
22
+ True
23
+
24
+ NOTE: objtype can be a single type (e.g. int or list) or a tuple of types.
25
+
26
+ WARNING: if obj is a sequence (e.g. list), may produce unexpected results.
27
+ Parent finds *one* parent (e.g. the last member of the sequence).
28
+ """
29
+ depth = 1 #XXX: always looking for the parent (only, right?)
30
+ chain = parents(obj, objtype, depth, ignore)
31
+ parent = chain.pop()
32
+ if parent is obj:
33
+ return None
34
+ return parent
35
+
36
+
37
+ def parents(obj, objtype, depth=1, ignore=()): #XXX: objtype=object ?
38
+ """Find the chain of referents for obj. Chain will end with obj.
39
+
40
+ objtype: an object type or tuple of types to search for
41
+ depth: search depth (e.g. depth=2 is 'grandparents')
42
+ ignore: an object or tuple of objects to ignore in the search
43
+ """
44
+ edge_func = gc.get_referents # looking for refs, not back_refs
45
+ predicate = lambda x: isinstance(x, objtype) # looking for parent type
46
+ #if objtype is None: predicate = lambda x: True #XXX: in obj.mro() ?
47
+ ignore = (ignore,) if not hasattr(ignore, '__len__') else ignore
48
+ ignore = (id(obj) for obj in ignore)
49
+ chain = find_chain(obj, predicate, edge_func, depth)[::-1]
50
+ #XXX: should pop off obj... ?
51
+ return chain
52
+
53
+
54
+ def children(obj, objtype, depth=1, ignore=()): #XXX: objtype=object ?
55
+ """Find the chain of referrers for obj. Chain will start with obj.
56
+
57
+ objtype: an object type or tuple of types to search for
58
+ depth: search depth (e.g. depth=2 is 'grandchildren')
59
+ ignore: an object or tuple of objects to ignore in the search
60
+
61
+ NOTE: a common thing to ignore is all globals, 'ignore=(globals(),)'
62
+
63
+ NOTE: repeated calls may yield different results, as python stores
64
+ the last value in the special variable '_'; thus, it is often good
65
+ to execute something to replace '_' (e.g. >>> 1+1).
66
+ """
67
+ edge_func = gc.get_referrers # looking for back_refs, not refs
68
+ predicate = lambda x: isinstance(x, objtype) # looking for child type
69
+ #if objtype is None: predicate = lambda x: True #XXX: in obj.mro() ?
70
+ ignore = (ignore,) if not hasattr(ignore, '__len__') else ignore
71
+ ignore = (id(obj) for obj in ignore)
72
+ chain = find_chain(obj, predicate, edge_func, depth, ignore)
73
+ #XXX: should pop off obj... ?
74
+ return chain
75
+
76
+
77
+ # more generic helper function (cut-n-paste from objgraph)
78
+ # Source at http://mg.pov.lt/objgraph/
79
+ # Copyright (c) 2008-2010 Marius Gedminas <marius@pov.lt>
80
+ # Copyright (c) 2010 Stefano Rivera <stefano@rivera.za.net>
81
+ # Released under the MIT licence (see objgraph/objgrah.py)
82
+
83
+ def find_chain(obj, predicate, edge_func, max_depth=20, extra_ignore=()):
84
+ queue = [obj]
85
+ depth = {id(obj): 0}
86
+ parent = {id(obj): None}
87
+ ignore = set(extra_ignore)
88
+ ignore.add(id(extra_ignore))
89
+ ignore.add(id(queue))
90
+ ignore.add(id(depth))
91
+ ignore.add(id(parent))
92
+ ignore.add(id(ignore))
93
+ ignore.add(id(sys._getframe())) # this function
94
+ ignore.add(id(sys._getframe(1))) # find_chain/find_backref_chain, likely
95
+ gc.collect()
96
+ while queue:
97
+ target = queue.pop(0)
98
+ if predicate(target):
99
+ chain = [target]
100
+ while parent[id(target)] is not None:
101
+ target = parent[id(target)]
102
+ chain.append(target)
103
+ return chain
104
+ tdepth = depth[id(target)]
105
+ if tdepth < max_depth:
106
+ referrers = edge_func(target)
107
+ ignore.add(id(referrers))
108
+ for source in referrers:
109
+ if id(source) in ignore:
110
+ continue
111
+ if id(source) not in depth:
112
+ depth[id(source)] = tdepth + 1
113
+ parent[id(source)] = target
114
+ queue.append(source)
115
+ return [obj] # not found
116
+
117
+
118
+ # backward compatibility
119
+ refobject = at
120
+
121
+
122
+ # EOF
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/session.py ADDED
@@ -0,0 +1,613 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Author: Leonardo Gama (@leogama)
5
+ # Copyright (c) 2008-2015 California Institute of Technology.
6
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
7
+ # License: 3-clause BSD. The full license text is available at:
8
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
9
+ """
10
+ Pickle and restore the intepreter session.
11
+ """
12
+
13
+ __all__ = [
14
+ 'dump_module', 'load_module', 'load_module_asdict',
15
+ 'dump_session', 'load_session' # backward compatibility
16
+ ]
17
+
18
+ import re
19
+ import os
20
+ import sys
21
+ import warnings
22
+
23
+ from dill import _dill, Pickler, Unpickler
24
+ from ._dill import (
25
+ BuiltinMethodType, FunctionType, MethodType, ModuleType, TypeType,
26
+ _import_module, _is_builtin_module, _is_imported_module, _main_module,
27
+ _reverse_typemap, __builtin__,
28
+ )
29
+
30
+ # Type hints.
31
+ from typing import Optional, Union
32
+
33
+ import pathlib
34
+ import tempfile
35
+
36
+ TEMPDIR = pathlib.PurePath(tempfile.gettempdir())
37
+
38
+ def _module_map():
39
+ """get map of imported modules"""
40
+ from collections import defaultdict
41
+ from types import SimpleNamespace
42
+ modmap = SimpleNamespace(
43
+ by_name=defaultdict(list),
44
+ by_id=defaultdict(list),
45
+ top_level={},
46
+ )
47
+ for modname, module in sys.modules.items():
48
+ if modname in ('__main__', '__mp_main__') or not isinstance(module, ModuleType):
49
+ continue
50
+ if '.' not in modname:
51
+ modmap.top_level[id(module)] = modname
52
+ for objname, modobj in module.__dict__.items():
53
+ modmap.by_name[objname].append((modobj, modname))
54
+ modmap.by_id[id(modobj)].append((modobj, objname, modname))
55
+ return modmap
56
+
57
+ IMPORTED_AS_TYPES = (ModuleType, TypeType, FunctionType, MethodType, BuiltinMethodType)
58
+ if 'PyCapsuleType' in _reverse_typemap:
59
+ IMPORTED_AS_TYPES += (_reverse_typemap['PyCapsuleType'],)
60
+ IMPORTED_AS_MODULES = ('ctypes', 'typing', 'subprocess', 'threading',
61
+ r'concurrent\.futures(\.\w+)?', r'multiprocessing(\.\w+)?')
62
+ IMPORTED_AS_MODULES = tuple(re.compile(x) for x in IMPORTED_AS_MODULES)
63
+
64
+ def _lookup_module(modmap, name, obj, main_module):
65
+ """lookup name or id of obj if module is imported"""
66
+ for modobj, modname in modmap.by_name[name]:
67
+ if modobj is obj and sys.modules[modname] is not main_module:
68
+ return modname, name
69
+ __module__ = getattr(obj, '__module__', None)
70
+ if isinstance(obj, IMPORTED_AS_TYPES) or (__module__ is not None
71
+ and any(regex.fullmatch(__module__) for regex in IMPORTED_AS_MODULES)):
72
+ for modobj, objname, modname in modmap.by_id[id(obj)]:
73
+ if sys.modules[modname] is not main_module:
74
+ return modname, objname
75
+ return None, None
76
+
77
+ def _stash_modules(main_module):
78
+ modmap = _module_map()
79
+ newmod = ModuleType(main_module.__name__)
80
+
81
+ imported = []
82
+ imported_as = []
83
+ imported_top_level = [] # keep separated for backward compatibility
84
+ original = {}
85
+ for name, obj in main_module.__dict__.items():
86
+ if obj is main_module:
87
+ original[name] = newmod # self-reference
88
+ elif obj is main_module.__dict__:
89
+ original[name] = newmod.__dict__
90
+ # Avoid incorrectly matching a singleton value in another package (ex.: __doc__).
91
+ elif any(obj is singleton for singleton in (None, False, True)) \
92
+ or isinstance(obj, ModuleType) and _is_builtin_module(obj): # always saved by ref
93
+ original[name] = obj
94
+ else:
95
+ source_module, objname = _lookup_module(modmap, name, obj, main_module)
96
+ if source_module is not None:
97
+ if objname == name:
98
+ imported.append((source_module, name))
99
+ else:
100
+ imported_as.append((source_module, objname, name))
101
+ else:
102
+ try:
103
+ imported_top_level.append((modmap.top_level[id(obj)], name))
104
+ except KeyError:
105
+ original[name] = obj
106
+
107
+ if len(original) < len(main_module.__dict__):
108
+ newmod.__dict__.update(original)
109
+ newmod.__dill_imported = imported
110
+ newmod.__dill_imported_as = imported_as
111
+ newmod.__dill_imported_top_level = imported_top_level
112
+ if getattr(newmod, '__loader__', None) is None and _is_imported_module(main_module):
113
+ # Trick _is_imported_module() to force saving as an imported module.
114
+ newmod.__loader__ = True # will be discarded by save_module()
115
+ return newmod
116
+ else:
117
+ return main_module
118
+
119
+ def _restore_modules(unpickler, main_module):
120
+ try:
121
+ for modname, name in main_module.__dict__.pop('__dill_imported'):
122
+ main_module.__dict__[name] = unpickler.find_class(modname, name)
123
+ for modname, objname, name in main_module.__dict__.pop('__dill_imported_as'):
124
+ main_module.__dict__[name] = unpickler.find_class(modname, objname)
125
+ for modname, name in main_module.__dict__.pop('__dill_imported_top_level'):
126
+ main_module.__dict__[name] = __import__(modname)
127
+ except KeyError:
128
+ pass
129
+
130
+ #NOTE: 06/03/15 renamed main_module to main
131
+ def dump_module(
132
+ filename: Union[str, os.PathLike] = None,
133
+ module: Optional[Union[ModuleType, str]] = None,
134
+ refimported: bool = False,
135
+ **kwds
136
+ ) -> None:
137
+ """Pickle the current state of :py:mod:`__main__` or another module to a file.
138
+
139
+ Save the contents of :py:mod:`__main__` (e.g. from an interactive
140
+ interpreter session), an imported module, or a module-type object (e.g.
141
+ built with :py:class:`~types.ModuleType`), to a file. The pickled
142
+ module can then be restored with the function :py:func:`load_module`.
143
+
144
+ Args:
145
+ filename: a path-like object or a writable stream. If `None`
146
+ (the default), write to a named file in a temporary directory.
147
+ module: a module object or the name of an importable module. If `None`
148
+ (the default), :py:mod:`__main__` is saved.
149
+ refimported: if `True`, all objects identified as having been imported
150
+ into the module's namespace are saved by reference. *Note:* this is
151
+ similar but independent from ``dill.settings[`byref`]``, as
152
+ ``refimported`` refers to virtually all imported objects, while
153
+ ``byref`` only affects select objects.
154
+ **kwds: extra keyword arguments passed to :py:class:`Pickler()`.
155
+
156
+ Raises:
157
+ :py:exc:`PicklingError`: if pickling fails.
158
+
159
+ Examples:
160
+
161
+ - Save current interpreter session state:
162
+
163
+ >>> import dill
164
+ >>> squared = lambda x: x*x
165
+ >>> dill.dump_module() # save state of __main__ to /tmp/session.pkl
166
+
167
+ - Save the state of an imported/importable module:
168
+
169
+ >>> import dill
170
+ >>> import pox
171
+ >>> pox.plus_one = lambda x: x+1
172
+ >>> dill.dump_module('pox_session.pkl', module=pox)
173
+
174
+ - Save the state of a non-importable, module-type object:
175
+
176
+ >>> import dill
177
+ >>> from types import ModuleType
178
+ >>> foo = ModuleType('foo')
179
+ >>> foo.values = [1,2,3]
180
+ >>> import math
181
+ >>> foo.sin = math.sin
182
+ >>> dill.dump_module('foo_session.pkl', module=foo, refimported=True)
183
+
184
+ - Restore the state of the saved modules:
185
+
186
+ >>> import dill
187
+ >>> dill.load_module()
188
+ >>> squared(2)
189
+ 4
190
+ >>> pox = dill.load_module('pox_session.pkl')
191
+ >>> pox.plus_one(1)
192
+ 2
193
+ >>> foo = dill.load_module('foo_session.pkl')
194
+ >>> [foo.sin(x) for x in foo.values]
195
+ [0.8414709848078965, 0.9092974268256817, 0.1411200080598672]
196
+
197
+ - Use `refimported` to save imported objects by reference:
198
+
199
+ >>> import dill
200
+ >>> from html.entities import html5
201
+ >>> type(html5), len(html5)
202
+ (dict, 2231)
203
+ >>> import io
204
+ >>> buf = io.BytesIO()
205
+ >>> dill.dump_module(buf) # saves __main__, with html5 saved by value
206
+ >>> len(buf.getvalue()) # pickle size in bytes
207
+ 71665
208
+ >>> buf = io.BytesIO()
209
+ >>> dill.dump_module(buf, refimported=True) # html5 saved by reference
210
+ >>> len(buf.getvalue())
211
+ 438
212
+
213
+ *Changed in version 0.3.6:* Function ``dump_session()`` was renamed to
214
+ ``dump_module()``. Parameters ``main`` and ``byref`` were renamed to
215
+ ``module`` and ``refimported``, respectively.
216
+
217
+ Note:
218
+ Currently, ``dill.settings['byref']`` and ``dill.settings['recurse']``
219
+ don't apply to this function.
220
+ """
221
+ for old_par, par in [('main', 'module'), ('byref', 'refimported')]:
222
+ if old_par in kwds:
223
+ message = "The argument %r has been renamed %r" % (old_par, par)
224
+ if old_par == 'byref':
225
+ message += " to distinguish it from dill.settings['byref']"
226
+ warnings.warn(message + ".", PendingDeprecationWarning)
227
+ if locals()[par]: # the defaults are None and False
228
+ raise TypeError("both %r and %r arguments were used" % (par, old_par))
229
+ refimported = kwds.pop('byref', refimported)
230
+ module = kwds.pop('main', module)
231
+
232
+ from .settings import settings
233
+ protocol = settings['protocol']
234
+ main = module
235
+ if main is None:
236
+ main = _main_module
237
+ elif isinstance(main, str):
238
+ main = _import_module(main)
239
+ if not isinstance(main, ModuleType):
240
+ raise TypeError("%r is not a module" % main)
241
+ if hasattr(filename, 'write'):
242
+ file = filename
243
+ else:
244
+ if filename is None:
245
+ filename = str(TEMPDIR/'session.pkl')
246
+ file = open(filename, 'wb')
247
+ try:
248
+ pickler = Pickler(file, protocol, **kwds)
249
+ pickler._original_main = main
250
+ if refimported:
251
+ main = _stash_modules(main)
252
+ pickler._main = main #FIXME: dill.settings are disabled
253
+ pickler._byref = False # disable pickling by name reference
254
+ pickler._recurse = False # disable pickling recursion for globals
255
+ pickler._session = True # is best indicator of when pickling a session
256
+ pickler._first_pass = True
257
+ pickler._main_modified = main is not pickler._original_main
258
+ pickler.dump(main)
259
+ finally:
260
+ if file is not filename: # if newly opened file
261
+ file.close()
262
+ return
263
+
264
+ # Backward compatibility.
265
+ def dump_session(filename=None, main=None, byref=False, **kwds):
266
+ warnings.warn("dump_session() has been renamed dump_module()", PendingDeprecationWarning)
267
+ dump_module(filename, module=main, refimported=byref, **kwds)
268
+ dump_session.__doc__ = dump_module.__doc__
269
+
270
+ class _PeekableReader:
271
+ """lightweight stream wrapper that implements peek()"""
272
+ def __init__(self, stream):
273
+ self.stream = stream
274
+ def read(self, n):
275
+ return self.stream.read(n)
276
+ def readline(self):
277
+ return self.stream.readline()
278
+ def tell(self):
279
+ return self.stream.tell()
280
+ def close(self):
281
+ return self.stream.close()
282
+ def peek(self, n):
283
+ stream = self.stream
284
+ try:
285
+ if hasattr(stream, 'flush'): stream.flush()
286
+ position = stream.tell()
287
+ stream.seek(position) # assert seek() works before reading
288
+ chunk = stream.read(n)
289
+ stream.seek(position)
290
+ return chunk
291
+ except (AttributeError, OSError):
292
+ raise NotImplementedError("stream is not peekable: %r", stream) from None
293
+
294
+ def _make_peekable(stream):
295
+ """return stream as an object with a peek() method"""
296
+ import io
297
+ if hasattr(stream, 'peek'):
298
+ return stream
299
+ if not (hasattr(stream, 'tell') and hasattr(stream, 'seek')):
300
+ try:
301
+ return io.BufferedReader(stream)
302
+ except Exception:
303
+ pass
304
+ return _PeekableReader(stream)
305
+
306
+ def _identify_module(file, main=None):
307
+ """identify the name of the module stored in the given file-type object"""
308
+ from pickletools import genops
309
+ UNICODE = {'UNICODE', 'BINUNICODE', 'SHORT_BINUNICODE'}
310
+ found_import = False
311
+ try:
312
+ for opcode, arg, pos in genops(file.peek(256)):
313
+ if not found_import:
314
+ if opcode.name in ('GLOBAL', 'SHORT_BINUNICODE') and \
315
+ arg.endswith('_import_module'):
316
+ found_import = True
317
+ else:
318
+ if opcode.name in UNICODE:
319
+ return arg
320
+ else:
321
+ raise UnpicklingError("reached STOP without finding main module")
322
+ except (NotImplementedError, ValueError) as error:
323
+ # ValueError occours when the end of the chunk is reached (without a STOP).
324
+ if isinstance(error, NotImplementedError) and main is not None:
325
+ # file is not peekable, but we have main.
326
+ return None
327
+ raise UnpicklingError("unable to identify main module") from error
328
+
329
+ def load_module(
330
+ filename: Union[str, os.PathLike] = None,
331
+ module: Optional[Union[ModuleType, str]] = None,
332
+ **kwds
333
+ ) -> Optional[ModuleType]:
334
+ """Update the selected module (default is :py:mod:`__main__`) with
335
+ the state saved at ``filename``.
336
+
337
+ Restore a module to the state saved with :py:func:`dump_module`. The
338
+ saved module can be :py:mod:`__main__` (e.g. an interpreter session),
339
+ an imported module, or a module-type object (e.g. created with
340
+ :py:class:`~types.ModuleType`).
341
+
342
+ When restoring the state of a non-importable module-type object, the
343
+ current instance of this module may be passed as the argument ``main``.
344
+ Otherwise, a new instance is created with :py:class:`~types.ModuleType`
345
+ and returned.
346
+
347
+ Args:
348
+ filename: a path-like object or a readable stream. If `None`
349
+ (the default), read from a named file in a temporary directory.
350
+ module: a module object or the name of an importable module;
351
+ the module name and kind (i.e. imported or non-imported) must
352
+ match the name and kind of the module stored at ``filename``.
353
+ **kwds: extra keyword arguments passed to :py:class:`Unpickler()`.
354
+
355
+ Raises:
356
+ :py:exc:`UnpicklingError`: if unpickling fails.
357
+ :py:exc:`ValueError`: if the argument ``main`` and module saved
358
+ at ``filename`` are incompatible.
359
+
360
+ Returns:
361
+ A module object, if the saved module is not :py:mod:`__main__` or
362
+ a module instance wasn't provided with the argument ``main``.
363
+
364
+ Examples:
365
+
366
+ - Save the state of some modules:
367
+
368
+ >>> import dill
369
+ >>> squared = lambda x: x*x
370
+ >>> dill.dump_module() # save state of __main__ to /tmp/session.pkl
371
+ >>>
372
+ >>> import pox # an imported module
373
+ >>> pox.plus_one = lambda x: x+1
374
+ >>> dill.dump_module('pox_session.pkl', module=pox)
375
+ >>>
376
+ >>> from types import ModuleType
377
+ >>> foo = ModuleType('foo') # a module-type object
378
+ >>> foo.values = [1,2,3]
379
+ >>> import math
380
+ >>> foo.sin = math.sin
381
+ >>> dill.dump_module('foo_session.pkl', module=foo, refimported=True)
382
+
383
+ - Restore the state of the interpreter:
384
+
385
+ >>> import dill
386
+ >>> dill.load_module() # updates __main__ from /tmp/session.pkl
387
+ >>> squared(2)
388
+ 4
389
+
390
+ - Load the saved state of an importable module:
391
+
392
+ >>> import dill
393
+ >>> pox = dill.load_module('pox_session.pkl')
394
+ >>> pox.plus_one(1)
395
+ 2
396
+ >>> import sys
397
+ >>> pox in sys.modules.values()
398
+ True
399
+
400
+ - Load the saved state of a non-importable module-type object:
401
+
402
+ >>> import dill
403
+ >>> foo = dill.load_module('foo_session.pkl')
404
+ >>> [foo.sin(x) for x in foo.values]
405
+ [0.8414709848078965, 0.9092974268256817, 0.1411200080598672]
406
+ >>> import math
407
+ >>> foo.sin is math.sin # foo.sin was saved by reference
408
+ True
409
+ >>> import sys
410
+ >>> foo in sys.modules.values()
411
+ False
412
+
413
+ - Update the state of a non-importable module-type object:
414
+
415
+ >>> import dill
416
+ >>> from types import ModuleType
417
+ >>> foo = ModuleType('foo')
418
+ >>> foo.values = ['a','b']
419
+ >>> foo.sin = lambda x: x*x
420
+ >>> dill.load_module('foo_session.pkl', module=foo)
421
+ >>> [foo.sin(x) for x in foo.values]
422
+ [0.8414709848078965, 0.9092974268256817, 0.1411200080598672]
423
+
424
+ *Changed in version 0.3.6:* Function ``load_session()`` was renamed to
425
+ ``load_module()``. Parameter ``main`` was renamed to ``module``.
426
+
427
+ See also:
428
+ :py:func:`load_module_asdict` to load the contents of module saved
429
+ with :py:func:`dump_module` into a dictionary.
430
+ """
431
+ if 'main' in kwds:
432
+ warnings.warn(
433
+ "The argument 'main' has been renamed 'module'.",
434
+ PendingDeprecationWarning
435
+ )
436
+ if module is not None:
437
+ raise TypeError("both 'module' and 'main' arguments were used")
438
+ module = kwds.pop('main')
439
+ main = module
440
+ if hasattr(filename, 'read'):
441
+ file = filename
442
+ else:
443
+ if filename is None:
444
+ filename = str(TEMPDIR/'session.pkl')
445
+ file = open(filename, 'rb')
446
+ try:
447
+ file = _make_peekable(file)
448
+ #FIXME: dill.settings are disabled
449
+ unpickler = Unpickler(file, **kwds)
450
+ unpickler._session = True
451
+
452
+ # Resolve unpickler._main
453
+ pickle_main = _identify_module(file, main)
454
+ if main is None and pickle_main is not None:
455
+ main = pickle_main
456
+ if isinstance(main, str):
457
+ if main.startswith('__runtime__.'):
458
+ # Create runtime module to load the session into.
459
+ main = ModuleType(main.partition('.')[-1])
460
+ else:
461
+ main = _import_module(main)
462
+ if main is not None:
463
+ if not isinstance(main, ModuleType):
464
+ raise TypeError("%r is not a module" % main)
465
+ unpickler._main = main
466
+ else:
467
+ main = unpickler._main
468
+
469
+ # Check against the pickle's main.
470
+ is_main_imported = _is_imported_module(main)
471
+ if pickle_main is not None:
472
+ is_runtime_mod = pickle_main.startswith('__runtime__.')
473
+ if is_runtime_mod:
474
+ pickle_main = pickle_main.partition('.')[-1]
475
+ error_msg = "can't update{} module{} %r with the saved state of{} module{} %r"
476
+ if is_runtime_mod and is_main_imported:
477
+ raise ValueError(
478
+ error_msg.format(" imported", "", "", "-type object")
479
+ % (main.__name__, pickle_main)
480
+ )
481
+ if not is_runtime_mod and not is_main_imported:
482
+ raise ValueError(
483
+ error_msg.format("", "-type object", " imported", "")
484
+ % (pickle_main, main.__name__)
485
+ )
486
+ if main.__name__ != pickle_main:
487
+ raise ValueError(error_msg.format("", "", "", "") % (main.__name__, pickle_main))
488
+
489
+ # This is for find_class() to be able to locate it.
490
+ if not is_main_imported:
491
+ runtime_main = '__runtime__.%s' % main.__name__
492
+ sys.modules[runtime_main] = main
493
+
494
+ loaded = unpickler.load()
495
+ finally:
496
+ if not hasattr(filename, 'read'): # if newly opened file
497
+ file.close()
498
+ try:
499
+ del sys.modules[runtime_main]
500
+ except (KeyError, NameError):
501
+ pass
502
+ assert loaded is main
503
+ _restore_modules(unpickler, main)
504
+ if main is _main_module or main is module:
505
+ return None
506
+ else:
507
+ return main
508
+
509
+ # Backward compatibility.
510
+ def load_session(filename=None, main=None, **kwds):
511
+ warnings.warn("load_session() has been renamed load_module().", PendingDeprecationWarning)
512
+ load_module(filename, module=main, **kwds)
513
+ load_session.__doc__ = load_module.__doc__
514
+
515
+ def load_module_asdict(
516
+ filename: Union[str, os.PathLike] = None,
517
+ update: bool = False,
518
+ **kwds
519
+ ) -> dict:
520
+ """
521
+ Load the contents of a saved module into a dictionary.
522
+
523
+ ``load_module_asdict()`` is the near-equivalent of::
524
+
525
+ lambda filename: vars(dill.load_module(filename)).copy()
526
+
527
+ however, does not alter the original module. Also, the path of
528
+ the loaded module is stored in the ``__session__`` attribute.
529
+
530
+ Args:
531
+ filename: a path-like object or a readable stream. If `None`
532
+ (the default), read from a named file in a temporary directory.
533
+ update: if `True`, initialize the dictionary with the current state
534
+ of the module prior to loading the state stored at filename.
535
+ **kwds: extra keyword arguments passed to :py:class:`Unpickler()`
536
+
537
+ Raises:
538
+ :py:exc:`UnpicklingError`: if unpickling fails
539
+
540
+ Returns:
541
+ A copy of the restored module's dictionary.
542
+
543
+ Note:
544
+ If ``update`` is True, the corresponding module may first be imported
545
+ into the current namespace before the saved state is loaded from
546
+ filename to the dictionary. Note that any module that is imported into
547
+ the current namespace as a side-effect of using ``update`` will not be
548
+ modified by loading the saved module in filename to a dictionary.
549
+
550
+ Example:
551
+ >>> import dill
552
+ >>> alist = [1, 2, 3]
553
+ >>> anum = 42
554
+ >>> dill.dump_module()
555
+ >>> anum = 0
556
+ >>> new_var = 'spam'
557
+ >>> main = dill.load_module_asdict()
558
+ >>> main['__name__'], main['__session__']
559
+ ('__main__', '/tmp/session.pkl')
560
+ >>> main is globals() # loaded objects don't reference globals
561
+ False
562
+ >>> main['alist'] == alist
563
+ True
564
+ >>> main['alist'] is alist # was saved by value
565
+ False
566
+ >>> main['anum'] == anum # changed after the session was saved
567
+ False
568
+ >>> new_var in main # would be True if the option 'update' was set
569
+ False
570
+ """
571
+ if 'module' in kwds:
572
+ raise TypeError("'module' is an invalid keyword argument for load_module_asdict()")
573
+ if hasattr(filename, 'read'):
574
+ file = filename
575
+ else:
576
+ if filename is None:
577
+ filename = str(TEMPDIR/'session.pkl')
578
+ file = open(filename, 'rb')
579
+ try:
580
+ file = _make_peekable(file)
581
+ main_name = _identify_module(file)
582
+ old_main = sys.modules.get(main_name)
583
+ main = ModuleType(main_name)
584
+ if update:
585
+ if old_main is None:
586
+ old_main = _import_module(main_name)
587
+ main.__dict__.update(old_main.__dict__)
588
+ else:
589
+ main.__builtins__ = __builtin__
590
+ sys.modules[main_name] = main
591
+ load_module(file, **kwds)
592
+ finally:
593
+ if not hasattr(filename, 'read'): # if newly opened file
594
+ file.close()
595
+ try:
596
+ if old_main is None:
597
+ del sys.modules[main_name]
598
+ else:
599
+ sys.modules[main_name] = old_main
600
+ except NameError: # failed before setting old_main
601
+ pass
602
+ main.__session__ = str(filename)
603
+ return main.__dict__
604
+
605
+
606
+ # Internal exports for backward compatibility with dill v0.3.5.1
607
+ # Can't be placed in dill._dill because of circular import problems.
608
+ for name in (
609
+ '_lookup_module', '_module_map', '_restore_modules', '_stash_modules',
610
+ 'dump_session', 'load_session' # backward compatibility functions
611
+ ):
612
+ setattr(_dill, name, globals()[name])
613
+ del name
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/settings.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2016 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+ """
9
+ global settings for Pickler
10
+ """
11
+
12
+ from pickle import DEFAULT_PROTOCOL
13
+
14
+ settings = {
15
+ #'main' : None,
16
+ 'protocol' : DEFAULT_PROTOCOL,
17
+ 'byref' : False,
18
+ #'strictio' : False,
19
+ 'fmode' : 0, #HANDLE_FMODE
20
+ 'recurse' : False,
21
+ 'ignore' : False,
22
+ }
23
+
24
+ del DEFAULT_PROTOCOL
25
+
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/source.py ADDED
@@ -0,0 +1,1017 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2016 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+ #
9
+ # inspired by inspect.py from Python-2.7.6
10
+ # inspect.py author: 'Ka-Ping Yee <ping@lfw.org>'
11
+ # inspect.py merged into original dill.source by Mike McKerns 4/13/14
12
+ """
13
+ Extensions to python's 'inspect' module, which can be used
14
+ to retrieve information from live python objects. The methods
15
+ defined in this module are augmented to facilitate access to
16
+ source code of interactively defined functions and classes,
17
+ as well as provide access to source code for objects defined
18
+ in a file.
19
+ """
20
+
21
+ __all__ = ['findsource', 'getsourcelines', 'getsource', 'indent', 'outdent', \
22
+ '_wrap', 'dumpsource', 'getname', '_namespace', 'getimport', \
23
+ '_importable', 'importable','isdynamic', 'isfrommain']
24
+
25
+ import linecache
26
+ import re
27
+ from inspect import (getblock, getfile, getmodule, getsourcefile, indentsize,
28
+ isbuiltin, isclass, iscode, isframe, isfunction, ismethod,
29
+ ismodule, istraceback)
30
+ from tokenize import TokenError
31
+
32
+ from ._dill import IS_IPYTHON
33
+
34
+
35
+ def isfrommain(obj):
36
+ "check if object was built in __main__"
37
+ module = getmodule(obj)
38
+ if module and module.__name__ == '__main__':
39
+ return True
40
+ return False
41
+
42
+
43
+ def isdynamic(obj):
44
+ "check if object was built in the interpreter"
45
+ try: file = getfile(obj)
46
+ except TypeError: file = None
47
+ if file == '<stdin>' and isfrommain(obj):
48
+ return True
49
+ return False
50
+
51
+
52
+ def _matchlambda(func, line):
53
+ """check if lambda object 'func' matches raw line of code 'line'"""
54
+ from .detect import code as getcode
55
+ from .detect import freevars, globalvars, varnames
56
+ dummy = lambda : '__this_is_a_big_dummy_function__'
57
+ # process the line (removing leading whitespace, etc)
58
+ lhs,rhs = line.split('lambda ',1)[-1].split(":", 1) #FIXME: if !1 inputs
59
+ try: #FIXME: unsafe
60
+ _ = eval("lambda %s : %s" % (lhs,rhs), globals(),locals())
61
+ except Exception: _ = dummy
62
+ # get code objects, for comparison
63
+ _, code = getcode(_).co_code, getcode(func).co_code
64
+ # check if func is in closure
65
+ _f = [line.count(i) for i in freevars(func).keys()]
66
+ if not _f: # not in closure
67
+ # check if code matches
68
+ if _ == code: return True
69
+ return False
70
+ # weak check on freevars
71
+ if not all(_f): return False #XXX: VERY WEAK
72
+ # weak check on varnames and globalvars
73
+ _f = varnames(func)
74
+ _f = [line.count(i) for i in _f[0]+_f[1]]
75
+ if _f and not all(_f): return False #XXX: VERY WEAK
76
+ _f = [line.count(i) for i in globalvars(func).keys()]
77
+ if _f and not all(_f): return False #XXX: VERY WEAK
78
+ # check if func is a double lambda
79
+ if (line.count('lambda ') > 1) and (lhs in freevars(func).keys()):
80
+ _lhs,_rhs = rhs.split('lambda ',1)[-1].split(":",1) #FIXME: if !1 inputs
81
+ try: #FIXME: unsafe
82
+ _f = eval("lambda %s : %s" % (_lhs,_rhs), globals(),locals())
83
+ except Exception: _f = dummy
84
+ # get code objects, for comparison
85
+ _, code = getcode(_f).co_code, getcode(func).co_code
86
+ if len(_) != len(code): return False
87
+ #NOTE: should be same code same order, but except for 't' and '\x88'
88
+ _ = set((i,j) for (i,j) in zip(_,code) if i != j)
89
+ if len(_) != 1: return False #('t','\x88')
90
+ return True
91
+ # check indentsize
92
+ if not indentsize(line): return False #FIXME: is this a good check???
93
+ # check if code 'pattern' matches
94
+ #XXX: or pattern match against dis.dis(code)? (or use uncompyle2?)
95
+ _ = _.split(_[0]) # 't' #XXX: remove matching values if starts the same?
96
+ _f = code.split(code[0]) # '\x88'
97
+ #NOTE: should be same code different order, with different first element
98
+ _ = dict(re.match(r'([\W\D\S])(.*)', _[i]).groups() for i in range(1,len(_)))
99
+ _f = dict(re.match(r'([\W\D\S])(.*)', _f[i]).groups() for i in range(1,len(_f)))
100
+ if (_.keys() == _f.keys()) and (sorted(_.values()) == sorted(_f.values())):
101
+ return True
102
+ return False
103
+
104
+
105
+ def findsource(object):
106
+ """Return the entire source file and starting line number for an object.
107
+ For interactively-defined objects, the 'file' is the interpreter's history.
108
+
109
+ The argument may be a module, class, method, function, traceback, frame,
110
+ or code object. The source code is returned as a list of all the lines
111
+ in the file and the line number indexes a line in that list. An IOError
112
+ is raised if the source code cannot be retrieved, while a TypeError is
113
+ raised for objects where the source code is unavailable (e.g. builtins)."""
114
+
115
+ module = getmodule(object)
116
+ try: file = getfile(module)
117
+ except TypeError: file = None
118
+ is_module_main = (module and module.__name__ == '__main__' and not file)
119
+ if IS_IPYTHON and is_module_main:
120
+ #FIXME: quick fix for functions and classes in IPython interpreter
121
+ try:
122
+ file = getfile(object)
123
+ sourcefile = getsourcefile(object)
124
+ except TypeError:
125
+ if isclass(object):
126
+ for object_method in filter(isfunction, object.__dict__.values()):
127
+ # look for a method of the class
128
+ file_candidate = getfile(object_method)
129
+ if not file_candidate.startswith('<ipython-input-'):
130
+ continue
131
+ file = file_candidate
132
+ sourcefile = getsourcefile(object_method)
133
+ break
134
+ if file:
135
+ lines = linecache.getlines(file)
136
+ else:
137
+ # fallback to use history
138
+ history = '\n'.join(get_ipython().history_manager.input_hist_parsed)
139
+ lines = [line + '\n' for line in history.splitlines()]
140
+ # use readline when working in interpreter (i.e. __main__ and not file)
141
+ elif is_module_main:
142
+ try:
143
+ import readline
144
+ err = ''
145
+ except ImportError:
146
+ import sys
147
+ err = sys.exc_info()[1].args[0]
148
+ if sys.platform[:3] == 'win':
149
+ err += ", please install 'pyreadline'"
150
+ if err:
151
+ raise IOError(err)
152
+ lbuf = readline.get_current_history_length()
153
+ lines = [readline.get_history_item(i)+'\n' for i in range(1,lbuf)]
154
+ else:
155
+ try: # special handling for class instances
156
+ if not isclass(object) and isclass(type(object)): # __class__
157
+ file = getfile(module)
158
+ sourcefile = getsourcefile(module)
159
+ else: # builtins fail with a TypeError
160
+ file = getfile(object)
161
+ sourcefile = getsourcefile(object)
162
+ except (TypeError, AttributeError): # fail with better error
163
+ file = getfile(object)
164
+ sourcefile = getsourcefile(object)
165
+ if not sourcefile and file[:1] + file[-1:] != '<>':
166
+ raise IOError('source code not available')
167
+ file = sourcefile if sourcefile else file
168
+
169
+ module = getmodule(object, file)
170
+ if module:
171
+ lines = linecache.getlines(file, module.__dict__)
172
+ else:
173
+ lines = linecache.getlines(file)
174
+
175
+ if not lines:
176
+ raise IOError('could not extract source code')
177
+
178
+ #FIXME: all below may fail if exec used (i.e. exec('f = lambda x:x') )
179
+ if ismodule(object):
180
+ return lines, 0
181
+
182
+ #NOTE: beneficial if search goes from end to start of buffer history
183
+ name = pat1 = obj = ''
184
+ pat2 = r'^(\s*@)'
185
+ # pat1b = r'^(\s*%s\W*=)' % name #FIXME: finds 'f = decorate(f)', not exec
186
+ if ismethod(object):
187
+ name = object.__name__
188
+ if name == '<lambda>': pat1 = r'(.*(?<!\w)lambda(:|\s))'
189
+ else: pat1 = r'^(\s*def\s)'
190
+ object = object.__func__
191
+ if isfunction(object):
192
+ name = object.__name__
193
+ if name == '<lambda>':
194
+ pat1 = r'(.*(?<!\w)lambda(:|\s))'
195
+ obj = object #XXX: better a copy?
196
+ else: pat1 = r'^(\s*def\s)'
197
+ object = object.__code__
198
+ if istraceback(object):
199
+ object = object.tb_frame
200
+ if isframe(object):
201
+ object = object.f_code
202
+ if iscode(object):
203
+ if not hasattr(object, 'co_firstlineno'):
204
+ raise IOError('could not find function definition')
205
+ stdin = object.co_filename == '<stdin>'
206
+ if stdin:
207
+ lnum = len(lines) - 1 # can't get lnum easily, so leverage pat
208
+ if not pat1: pat1 = r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)'
209
+ else:
210
+ lnum = object.co_firstlineno - 1
211
+ pat1 = r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)'
212
+ pat1 = re.compile(pat1); pat2 = re.compile(pat2)
213
+ #XXX: candidate_lnum = [n for n in range(lnum) if pat1.match(lines[n])]
214
+ while lnum > 0: #XXX: won't find decorators in <stdin> ?
215
+ line = lines[lnum]
216
+ if pat1.match(line):
217
+ if not stdin: break # co_firstlineno does the job
218
+ if name == '<lambda>': # hackery needed to confirm a match
219
+ if _matchlambda(obj, line): break
220
+ else: # not a lambda, just look for the name
221
+ if name in line: # need to check for decorator...
222
+ hats = 0
223
+ for _lnum in range(lnum-1,-1,-1):
224
+ if pat2.match(lines[_lnum]): hats += 1
225
+ else: break
226
+ lnum = lnum - hats
227
+ break
228
+ lnum = lnum - 1
229
+ return lines, lnum
230
+
231
+ try: # turn instances into classes
232
+ if not isclass(object) and isclass(type(object)): # __class__
233
+ object = object.__class__ #XXX: sometimes type(class) is better?
234
+ #XXX: we don't find how the instance was built
235
+ except AttributeError: pass
236
+ if isclass(object):
237
+ name = object.__name__
238
+ pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
239
+ # make some effort to find the best matching class definition:
240
+ # use the one with the least indentation, which is the one
241
+ # that's most probably not inside a function definition.
242
+ candidates = []
243
+ for i in range(len(lines)-1,-1,-1):
244
+ match = pat.match(lines[i])
245
+ if match:
246
+ # if it's at toplevel, it's already the best one
247
+ if lines[i][0] == 'c':
248
+ return lines, i
249
+ # else add whitespace to candidate list
250
+ candidates.append((match.group(1), i))
251
+ if candidates:
252
+ # this will sort by whitespace, and by line number,
253
+ # less whitespace first #XXX: should sort high lnum before low
254
+ candidates.sort()
255
+ return lines, candidates[0][1]
256
+ else:
257
+ raise IOError('could not find class definition')
258
+ raise IOError('could not find code object')
259
+
260
+
261
+ def getblocks(object, lstrip=False, enclosing=False, locate=False):
262
+ """Return a list of source lines and starting line number for an object.
263
+ Interactively-defined objects refer to lines in the interpreter's history.
264
+
265
+ If enclosing=True, then also return any enclosing code.
266
+ If lstrip=True, ensure there is no indentation in the first line of code.
267
+ If locate=True, then also return the line number for the block of code.
268
+
269
+ DEPRECATED: use 'getsourcelines' instead
270
+ """
271
+ lines, lnum = findsource(object)
272
+
273
+ if ismodule(object):
274
+ if lstrip: lines = _outdent(lines)
275
+ return ([lines], [0]) if locate is True else [lines]
276
+
277
+ #XXX: 'enclosing' means: closures only? or classes and files?
278
+ indent = indentsize(lines[lnum])
279
+ block = getblock(lines[lnum:]) #XXX: catch any TokenError here?
280
+
281
+ if not enclosing or not indent:
282
+ if lstrip: block = _outdent(block)
283
+ return ([block], [lnum]) if locate is True else [block]
284
+
285
+ pat1 = r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))'; pat1 = re.compile(pat1)
286
+ pat2 = r'^(\s*@)'; pat2 = re.compile(pat2)
287
+ #pat3 = r'^(\s*class\s)'; pat3 = re.compile(pat3) #XXX: enclosing class?
288
+ #FIXME: bound methods need enclosing class (and then instantiation)
289
+ # *or* somehow apply a partial using the instance
290
+
291
+ skip = 0
292
+ line = 0
293
+ blocks = []; _lnum = []
294
+ target = ''.join(block)
295
+ while line <= lnum: #XXX: repeat lnum? or until line < lnum?
296
+ # see if starts with ('def','lambda') and contains our target block
297
+ if pat1.match(lines[line]):
298
+ if not skip:
299
+ try: code = getblock(lines[line:])
300
+ except TokenError: code = [lines[line]]
301
+ if indentsize(lines[line]) > indent: #XXX: should be >= ?
302
+ line += len(code) - skip
303
+ elif target in ''.join(code):
304
+ blocks.append(code) # save code block as the potential winner
305
+ _lnum.append(line - skip) # save the line number for the match
306
+ line += len(code) - skip
307
+ else:
308
+ line += 1
309
+ skip = 0
310
+ # find skip: the number of consecutive decorators
311
+ elif pat2.match(lines[line]):
312
+ try: code = getblock(lines[line:])
313
+ except TokenError: code = [lines[line]]
314
+ skip = 1
315
+ for _line in code[1:]: # skip lines that are decorators
316
+ if not pat2.match(_line): break
317
+ skip += 1
318
+ line += skip
319
+ # no match: reset skip and go to the next line
320
+ else:
321
+ line +=1
322
+ skip = 0
323
+
324
+ if not blocks:
325
+ blocks = [block]
326
+ _lnum = [lnum]
327
+ if lstrip: blocks = [_outdent(block) for block in blocks]
328
+ # return last match
329
+ return (blocks, _lnum) if locate is True else blocks
330
+
331
+
332
+ def getsourcelines(object, lstrip=False, enclosing=False):
333
+ """Return a list of source lines and starting line number for an object.
334
+ Interactively-defined objects refer to lines in the interpreter's history.
335
+
336
+ The argument may be a module, class, method, function, traceback, frame,
337
+ or code object. The source code is returned as a list of the lines
338
+ corresponding to the object and the line number indicates where in the
339
+ original source file the first line of code was found. An IOError is
340
+ raised if the source code cannot be retrieved, while a TypeError is
341
+ raised for objects where the source code is unavailable (e.g. builtins).
342
+
343
+ If lstrip=True, ensure there is no indentation in the first line of code.
344
+ If enclosing=True, then also return any enclosing code."""
345
+ code, n = getblocks(object, lstrip=lstrip, enclosing=enclosing, locate=True)
346
+ return code[-1], n[-1]
347
+
348
+
349
+ #NOTE: broke backward compatibility 4/16/14 (was lstrip=True, force=True)
350
+ def getsource(object, alias='', lstrip=False, enclosing=False, \
351
+ force=False, builtin=False):
352
+ """Return the text of the source code for an object. The source code for
353
+ interactively-defined objects are extracted from the interpreter's history.
354
+
355
+ The argument may be a module, class, method, function, traceback, frame,
356
+ or code object. The source code is returned as a single string. An
357
+ IOError is raised if the source code cannot be retrieved, while a
358
+ TypeError is raised for objects where the source code is unavailable
359
+ (e.g. builtins).
360
+
361
+ If alias is provided, then add a line of code that renames the object.
362
+ If lstrip=True, ensure there is no indentation in the first line of code.
363
+ If enclosing=True, then also return any enclosing code.
364
+ If force=True, catch (TypeError,IOError) and try to use import hooks.
365
+ If builtin=True, force an import for any builtins
366
+ """
367
+ # hascode denotes a callable
368
+ hascode = _hascode(object)
369
+ # is a class instance type (and not in builtins)
370
+ instance = _isinstance(object)
371
+
372
+ # get source lines; if fail, try to 'force' an import
373
+ try: # fails for builtins, and other assorted object types
374
+ lines, lnum = getsourcelines(object, enclosing=enclosing)
375
+ except (TypeError, IOError): # failed to get source, resort to import hooks
376
+ if not force: # don't try to get types that findsource can't get
377
+ raise
378
+ if not getmodule(object): # get things like 'None' and '1'
379
+ if not instance: return getimport(object, alias, builtin=builtin)
380
+ # special handling (numpy arrays, ...)
381
+ _import = getimport(object, builtin=builtin)
382
+ name = getname(object, force=True)
383
+ _alias = "%s = " % alias if alias else ""
384
+ if alias == name: _alias = ""
385
+ return _import+_alias+"%s\n" % name
386
+ else: #FIXME: could use a good bit of cleanup, since using getimport...
387
+ if not instance: return getimport(object, alias, builtin=builtin)
388
+ # now we are dealing with an instance...
389
+ name = object.__class__.__name__
390
+ module = object.__module__
391
+ if module in ['builtins','__builtin__']:
392
+ return getimport(object, alias, builtin=builtin)
393
+ else: #FIXME: leverage getimport? use 'from module import name'?
394
+ lines, lnum = ["%s = __import__('%s', fromlist=['%s']).%s\n" % (name,module,name,name)], 0
395
+ obj = eval(lines[0].lstrip(name + ' = '))
396
+ lines, lnum = getsourcelines(obj, enclosing=enclosing)
397
+
398
+ # strip leading indent (helps ensure can be imported)
399
+ if lstrip or alias:
400
+ lines = _outdent(lines)
401
+
402
+ # instantiate, if there's a nice repr #XXX: BAD IDEA???
403
+ if instance: #and force: #XXX: move into findsource or getsourcelines ?
404
+ if '(' in repr(object): lines.append('%r\n' % object)
405
+ #else: #XXX: better to somehow to leverage __reduce__ ?
406
+ # reconstructor,args = object.__reduce__()
407
+ # _ = reconstructor(*args)
408
+ else: # fall back to serialization #XXX: bad idea?
409
+ #XXX: better not duplicate work? #XXX: better new/enclose=True?
410
+ lines = dumpsource(object, alias='', new=force, enclose=False)
411
+ lines, lnum = [line+'\n' for line in lines.split('\n')][:-1], 0
412
+ #else: object.__code__ # raise AttributeError
413
+
414
+ # add an alias to the source code
415
+ if alias:
416
+ if hascode:
417
+ skip = 0
418
+ for line in lines: # skip lines that are decorators
419
+ if not line.startswith('@'): break
420
+ skip += 1
421
+ #XXX: use regex from findsource / getsourcelines ?
422
+ if lines[skip].lstrip().startswith('def '): # we have a function
423
+ if alias != object.__name__:
424
+ lines.append('\n%s = %s\n' % (alias, object.__name__))
425
+ elif 'lambda ' in lines[skip]: # we have a lambda
426
+ if alias != lines[skip].split('=')[0].strip():
427
+ lines[skip] = '%s = %s' % (alias, lines[skip])
428
+ else: # ...try to use the object's name
429
+ if alias != object.__name__:
430
+ lines.append('\n%s = %s\n' % (alias, object.__name__))
431
+ else: # class or class instance
432
+ if instance:
433
+ if alias != lines[-1].split('=')[0].strip():
434
+ lines[-1] = ('%s = ' % alias) + lines[-1]
435
+ else:
436
+ name = getname(object, force=True) or object.__name__
437
+ if alias != name:
438
+ lines.append('\n%s = %s\n' % (alias, name))
439
+ return ''.join(lines)
440
+
441
+
442
+ def _hascode(object):
443
+ '''True if object has an attribute that stores it's __code__'''
444
+ return getattr(object,'__code__',None) or getattr(object,'func_code',None)
445
+
446
+ def _isinstance(object):
447
+ '''True if object is a class instance type (and is not a builtin)'''
448
+ if _hascode(object) or isclass(object) or ismodule(object):
449
+ return False
450
+ if istraceback(object) or isframe(object) or iscode(object):
451
+ return False
452
+ # special handling (numpy arrays, ...)
453
+ if not getmodule(object) and getmodule(type(object)).__name__ in ['numpy']:
454
+ return True
455
+ # # check if is instance of a builtin
456
+ # if not getmodule(object) and getmodule(type(object)).__name__ in ['__builtin__','builtins']:
457
+ # return False
458
+ _types = ('<class ',"<type 'instance'>")
459
+ if not repr(type(object)).startswith(_types): #FIXME: weak hack
460
+ return False
461
+ if not getmodule(object) or object.__module__ in ['builtins','__builtin__'] or getname(object, force=True) in ['array']:
462
+ return False
463
+ return True # by process of elimination... it's what we want
464
+
465
+
466
+ def _intypes(object):
467
+ '''check if object is in the 'types' module'''
468
+ import types
469
+ # allow user to pass in object or object.__name__
470
+ if type(object) is not type(''):
471
+ object = getname(object, force=True)
472
+ if object == 'ellipsis': object = 'EllipsisType'
473
+ return True if hasattr(types, object) else False
474
+
475
+
476
+ def _isstring(object): #XXX: isstringlike better?
477
+ '''check if object is a string-like type'''
478
+ return isinstance(object, (str, bytes))
479
+
480
+
481
+ def indent(code, spaces=4):
482
+ '''indent a block of code with whitespace (default is 4 spaces)'''
483
+ indent = indentsize(code)
484
+ if type(spaces) is int: spaces = ' '*spaces
485
+ # if '\t' is provided, will indent with a tab
486
+ nspaces = indentsize(spaces)
487
+ # blank lines (etc) need to be ignored
488
+ lines = code.split('\n')
489
+ ## stq = "'''"; dtq = '"""'
490
+ ## in_stq = in_dtq = False
491
+ for i in range(len(lines)):
492
+ #FIXME: works... but shouldn't indent 2nd+ lines of multiline doc
493
+ _indent = indentsize(lines[i])
494
+ if indent > _indent: continue
495
+ lines[i] = spaces+lines[i]
496
+ ## #FIXME: may fail when stq and dtq in same line (depends on ordering)
497
+ ## nstq, ndtq = lines[i].count(stq), lines[i].count(dtq)
498
+ ## if not in_dtq and not in_stq:
499
+ ## lines[i] = spaces+lines[i] # we indent
500
+ ## # entering a comment block
501
+ ## if nstq%2: in_stq = not in_stq
502
+ ## if ndtq%2: in_dtq = not in_dtq
503
+ ## # leaving a comment block
504
+ ## elif in_dtq and ndtq%2: in_dtq = not in_dtq
505
+ ## elif in_stq and nstq%2: in_stq = not in_stq
506
+ ## else: pass
507
+ if lines[-1].strip() == '': lines[-1] = ''
508
+ return '\n'.join(lines)
509
+
510
+
511
+ def _outdent(lines, spaces=None, all=True):
512
+ '''outdent lines of code, accounting for docs and line continuations'''
513
+ indent = indentsize(lines[0])
514
+ if spaces is None or spaces > indent or spaces < 0: spaces = indent
515
+ for i in range(len(lines) if all else 1):
516
+ #FIXME: works... but shouldn't outdent 2nd+ lines of multiline doc
517
+ _indent = indentsize(lines[i])
518
+ if spaces > _indent: _spaces = _indent
519
+ else: _spaces = spaces
520
+ lines[i] = lines[i][_spaces:]
521
+ return lines
522
+
523
+ def outdent(code, spaces=None, all=True):
524
+ '''outdent a block of code (default is to strip all leading whitespace)'''
525
+ indent = indentsize(code)
526
+ if spaces is None or spaces > indent or spaces < 0: spaces = indent
527
+ #XXX: will this delete '\n' in some cases?
528
+ if not all: return code[spaces:]
529
+ return '\n'.join(_outdent(code.split('\n'), spaces=spaces, all=all))
530
+
531
+
532
+ #XXX: not sure what the point of _wrap is...
533
+ __globals__ = globals()
534
+ __locals__ = locals()
535
+ def _wrap(f):
536
+ """ encapsulate a function and it's __import__ """
537
+ def func(*args, **kwds):
538
+ try:
539
+ # _ = eval(getsource(f, force=True)) #XXX: safer but less robust
540
+ exec(getimportable(f, alias='_'), __globals__, __locals__)
541
+ except Exception:
542
+ raise ImportError('cannot import name ' + f.__name__)
543
+ return _(*args, **kwds)
544
+ func.__name__ = f.__name__
545
+ func.__doc__ = f.__doc__
546
+ return func
547
+
548
+
549
+ def _enclose(object, alias=''): #FIXME: needs alias to hold returned object
550
+ """create a function enclosure around the source of some object"""
551
+ #XXX: dummy and stub should append a random string
552
+ dummy = '__this_is_a_big_dummy_enclosing_function__'
553
+ stub = '__this_is_a_stub_variable__'
554
+ code = 'def %s():\n' % dummy
555
+ code += indent(getsource(object, alias=stub, lstrip=True, force=True))
556
+ code += indent('return %s\n' % stub)
557
+ if alias: code += '%s = ' % alias
558
+ code += '%s(); del %s\n' % (dummy, dummy)
559
+ #code += "globals().pop('%s',lambda :None)()\n" % dummy
560
+ return code
561
+
562
+
563
+ def dumpsource(object, alias='', new=False, enclose=True):
564
+ """'dump to source', where the code includes a pickled object.
565
+
566
+ If new=True and object is a class instance, then create a new
567
+ instance using the unpacked class source code. If enclose, then
568
+ create the object inside a function enclosure (thus minimizing
569
+ any global namespace pollution).
570
+ """
571
+ from dill import dumps
572
+ pik = repr(dumps(object))
573
+ code = 'import dill\n'
574
+ if enclose:
575
+ stub = '__this_is_a_stub_variable__' #XXX: *must* be same _enclose.stub
576
+ pre = '%s = ' % stub
577
+ new = False #FIXME: new=True doesn't work with enclose=True
578
+ else:
579
+ stub = alias
580
+ pre = '%s = ' % stub if alias else alias
581
+
582
+ # if a 'new' instance is not needed, then just dump and load
583
+ if not new or not _isinstance(object):
584
+ code += pre + 'dill.loads(%s)\n' % pik
585
+ else: #XXX: other cases where source code is needed???
586
+ code += getsource(object.__class__, alias='', lstrip=True, force=True)
587
+ mod = repr(object.__module__) # should have a module (no builtins here)
588
+ code += pre + 'dill.loads(%s.replace(b%s,bytes(__name__,"UTF-8")))\n' % (pik,mod)
589
+ #code += 'del %s' % object.__class__.__name__ #NOTE: kills any existing!
590
+
591
+ if enclose:
592
+ # generation of the 'enclosure'
593
+ dummy = '__this_is_a_big_dummy_object__'
594
+ dummy = _enclose(dummy, alias=alias)
595
+ # hack to replace the 'dummy' with the 'real' code
596
+ dummy = dummy.split('\n')
597
+ code = dummy[0]+'\n' + indent(code) + '\n'.join(dummy[-3:])
598
+
599
+ return code #XXX: better 'dumpsourcelines', returning list of lines?
600
+
601
+
602
+ def getname(obj, force=False, fqn=False): #XXX: throw(?) to raise error on fail?
603
+ """get the name of the object. for lambdas, get the name of the pointer """
604
+ if fqn: return '.'.join(_namespace(obj))
605
+ module = getmodule(obj)
606
+ if not module: # things like "None" and "1"
607
+ if not force: return None
608
+ return repr(obj)
609
+ try:
610
+ #XXX: 'wrong' for decorators and curried functions ?
611
+ # if obj.func_closure: ...use logic from getimportable, etc ?
612
+ name = obj.__name__
613
+ if name == '<lambda>':
614
+ return getsource(obj).split('=',1)[0].strip()
615
+ # handle some special cases
616
+ if module.__name__ in ['builtins','__builtin__']:
617
+ if name == 'ellipsis': name = 'EllipsisType'
618
+ return name
619
+ except AttributeError: #XXX: better to just throw AttributeError ?
620
+ if not force: return None
621
+ name = repr(obj)
622
+ if name.startswith('<'): # or name.split('('):
623
+ return None
624
+ return name
625
+
626
+
627
+ def _namespace(obj):
628
+ """_namespace(obj); return namespace hierarchy (as a list of names)
629
+ for the given object. For an instance, find the class hierarchy.
630
+
631
+ For example:
632
+
633
+ >>> from functools import partial
634
+ >>> p = partial(int, base=2)
635
+ >>> _namespace(p)
636
+ [\'functools\', \'partial\']
637
+ """
638
+ # mostly for functions and modules and such
639
+ #FIXME: 'wrong' for decorators and curried functions
640
+ try: #XXX: needs some work and testing on different types
641
+ module = qual = str(getmodule(obj)).split()[1].strip('>').strip('"').strip("'")
642
+ qual = qual.split('.')
643
+ if ismodule(obj):
644
+ return qual
645
+ # get name of a lambda, function, etc
646
+ name = getname(obj) or obj.__name__ # failing, raise AttributeError
647
+ # check special cases (NoneType, ...)
648
+ if module in ['builtins','__builtin__']: # BuiltinFunctionType
649
+ if _intypes(name): return ['types'] + [name]
650
+ return qual + [name] #XXX: can be wrong for some aliased objects
651
+ except Exception: pass
652
+ # special case: numpy.inf and numpy.nan (we don't want them as floats)
653
+ if str(obj) in ['inf','nan','Inf','NaN']: # is more, but are they needed?
654
+ return ['numpy'] + [str(obj)]
655
+ # mostly for classes and class instances and such
656
+ module = getattr(obj.__class__, '__module__', None)
657
+ qual = str(obj.__class__)
658
+ try: qual = qual[qual.index("'")+1:-2]
659
+ except ValueError: pass # str(obj.__class__) made the 'try' unnecessary
660
+ qual = qual.split(".")
661
+ if module in ['builtins','__builtin__']:
662
+ # check special cases (NoneType, Ellipsis, ...)
663
+ if qual[-1] == 'ellipsis': qual[-1] = 'EllipsisType'
664
+ if _intypes(qual[-1]): module = 'types' #XXX: BuiltinFunctionType
665
+ qual = [module] + qual
666
+ return qual
667
+
668
+
669
+ #NOTE: 05/25/14 broke backward compatibility: added 'alias' as 3rd argument
670
+ def _getimport(head, tail, alias='', verify=True, builtin=False):
671
+ """helper to build a likely import string from head and tail of namespace.
672
+ ('head','tail') are used in the following context: "from head import tail"
673
+
674
+ If verify=True, then test the import string before returning it.
675
+ If builtin=True, then force an import for builtins where possible.
676
+ If alias is provided, then rename the object on import.
677
+ """
678
+ # special handling for a few common types
679
+ if tail in ['Ellipsis', 'NotImplemented'] and head in ['types']:
680
+ head = len.__module__
681
+ elif tail in ['None'] and head in ['types']:
682
+ _alias = '%s = ' % alias if alias else ''
683
+ if alias == tail: _alias = ''
684
+ return _alias+'%s\n' % tail
685
+ # we don't need to import from builtins, so return ''
686
+ # elif tail in ['NoneType','int','float','long','complex']: return '' #XXX: ?
687
+ if head in ['builtins','__builtin__']:
688
+ # special cases (NoneType, Ellipsis, ...) #XXX: BuiltinFunctionType
689
+ if tail == 'ellipsis': tail = 'EllipsisType'
690
+ if _intypes(tail): head = 'types'
691
+ elif not builtin:
692
+ _alias = '%s = ' % alias if alias else ''
693
+ if alias == tail: _alias = ''
694
+ return _alias+'%s\n' % tail
695
+ else: pass # handle builtins below
696
+ # get likely import string
697
+ if not head: _str = "import %s" % tail
698
+ else: _str = "from %s import %s" % (head, tail)
699
+ _alias = " as %s\n" % alias if alias else "\n"
700
+ if alias == tail: _alias = "\n"
701
+ _str += _alias
702
+ # FIXME: fails on most decorators, currying, and such...
703
+ # (could look for magic __wrapped__ or __func__ attr)
704
+ # (could fix in 'namespace' to check obj for closure)
705
+ if verify and not head.startswith('dill.'):# weird behavior for dill
706
+ #print(_str)
707
+ try: exec(_str) #XXX: check if == obj? (name collision)
708
+ except ImportError: #XXX: better top-down or bottom-up recursion?
709
+ _head = head.rsplit(".",1)[0] #(or get all, then compare == obj?)
710
+ if not _head: raise
711
+ if _head != head:
712
+ _str = _getimport(_head, tail, alias, verify)
713
+ return _str
714
+
715
+
716
+ #XXX: rename builtin to force? vice versa? verify to force? (as in getsource)
717
+ #NOTE: 05/25/14 broke backward compatibility: added 'alias' as 2nd argument
718
+ def getimport(obj, alias='', verify=True, builtin=False, enclosing=False):
719
+ """get the likely import string for the given object
720
+
721
+ obj is the object to inspect
722
+ If verify=True, then test the import string before returning it.
723
+ If builtin=True, then force an import for builtins where possible.
724
+ If enclosing=True, get the import for the outermost enclosing callable.
725
+ If alias is provided, then rename the object on import.
726
+ """
727
+ if enclosing:
728
+ from .detect import outermost
729
+ _obj = outermost(obj)
730
+ obj = _obj if _obj else obj
731
+ # get the namespace
732
+ qual = _namespace(obj)
733
+ head = '.'.join(qual[:-1])
734
+ tail = qual[-1]
735
+ # for named things... with a nice repr #XXX: move into _namespace?
736
+ try: # look for '<...>' and be mindful it might be in lists, dicts, etc...
737
+ name = repr(obj).split('<',1)[1].split('>',1)[1]
738
+ name = None # we have a 'object'-style repr
739
+ except Exception: # it's probably something 'importable'
740
+ if head in ['builtins','__builtin__']:
741
+ name = repr(obj) #XXX: catch [1,2], (1,2), set([1,2])... others?
742
+ else:
743
+ name = repr(obj).split('(')[0]
744
+ #if not repr(obj).startswith('<'): name = repr(obj).split('(')[0]
745
+ #else: name = None
746
+ if name: # try using name instead of tail
747
+ try: return _getimport(head, name, alias, verify, builtin)
748
+ except ImportError: pass
749
+ except SyntaxError:
750
+ if head in ['builtins','__builtin__']:
751
+ _alias = '%s = ' % alias if alias else ''
752
+ if alias == name: _alias = ''
753
+ return _alias+'%s\n' % name
754
+ else: pass
755
+ try:
756
+ #if type(obj) is type(abs): _builtin = builtin # BuiltinFunctionType
757
+ #else: _builtin = False
758
+ return _getimport(head, tail, alias, verify, builtin)
759
+ except ImportError:
760
+ raise # could do some checking against obj
761
+ except SyntaxError:
762
+ if head in ['builtins','__builtin__']:
763
+ _alias = '%s = ' % alias if alias else ''
764
+ if alias == tail: _alias = ''
765
+ return _alias+'%s\n' % tail
766
+ raise # could do some checking against obj
767
+
768
+
769
+ def _importable(obj, alias='', source=None, enclosing=False, force=True, \
770
+ builtin=True, lstrip=True):
771
+ """get an import string (or the source code) for the given object
772
+
773
+ This function will attempt to discover the name of the object, or the repr
774
+ of the object, or the source code for the object. To attempt to force
775
+ discovery of the source code, use source=True, to attempt to force the
776
+ use of an import, use source=False; otherwise an import will be sought
777
+ for objects not defined in __main__. The intent is to build a string
778
+ that can be imported from a python file. obj is the object to inspect.
779
+ If alias is provided, then rename the object with the given alias.
780
+
781
+ If source=True, use these options:
782
+ If enclosing=True, then also return any enclosing code.
783
+ If force=True, catch (TypeError,IOError) and try to use import hooks.
784
+ If lstrip=True, ensure there is no indentation in the first line of code.
785
+
786
+ If source=False, use these options:
787
+ If enclosing=True, get the import for the outermost enclosing callable.
788
+ If force=True, then don't test the import string before returning it.
789
+ If builtin=True, then force an import for builtins where possible.
790
+ """
791
+ if source is None:
792
+ source = True if isfrommain(obj) else False
793
+ if source: # first try to get the source
794
+ try:
795
+ return getsource(obj, alias, enclosing=enclosing, \
796
+ force=force, lstrip=lstrip, builtin=builtin)
797
+ except Exception: pass
798
+ try:
799
+ if not _isinstance(obj):
800
+ return getimport(obj, alias, enclosing=enclosing, \
801
+ verify=(not force), builtin=builtin)
802
+ # first 'get the import', then 'get the instance'
803
+ _import = getimport(obj, enclosing=enclosing, \
804
+ verify=(not force), builtin=builtin)
805
+ name = getname(obj, force=True)
806
+ if not name:
807
+ raise AttributeError("object has no atribute '__name__'")
808
+ _alias = "%s = " % alias if alias else ""
809
+ if alias == name: _alias = ""
810
+ return _import+_alias+"%s\n" % name
811
+
812
+ except Exception: pass
813
+ if not source: # try getsource, only if it hasn't been tried yet
814
+ try:
815
+ return getsource(obj, alias, enclosing=enclosing, \
816
+ force=force, lstrip=lstrip, builtin=builtin)
817
+ except Exception: pass
818
+ # get the name (of functions, lambdas, and classes)
819
+ # or hope that obj can be built from the __repr__
820
+ #XXX: what to do about class instances and such?
821
+ obj = getname(obj, force=force)
822
+ # we either have __repr__ or __name__ (or None)
823
+ if not obj or obj.startswith('<'):
824
+ raise AttributeError("object has no atribute '__name__'")
825
+ _alias = '%s = ' % alias if alias else ''
826
+ if alias == obj: _alias = ''
827
+ return _alias+'%s\n' % obj
828
+ #XXX: possible failsafe... (for example, for instances when source=False)
829
+ # "import dill; result = dill.loads(<pickled_object>); # repr(<object>)"
830
+
831
+ def _closuredimport(func, alias='', builtin=False):
832
+ """get import for closured objects; return a dict of 'name' and 'import'"""
833
+ import re
834
+ from .detect import freevars, outermost
835
+ free_vars = freevars(func)
836
+ func_vars = {}
837
+ # split into 'funcs' and 'non-funcs'
838
+ for name,obj in list(free_vars.items()):
839
+ if not isfunction(obj): continue
840
+ # get import for 'funcs'
841
+ fobj = free_vars.pop(name)
842
+ src = getsource(fobj)
843
+ if src.lstrip().startswith('@'): # we have a decorator
844
+ src = getimport(fobj, alias=alias, builtin=builtin)
845
+ else: # we have to "hack" a bit... and maybe be lucky
846
+ encl = outermost(func)
847
+ # pattern: 'func = enclosing(fobj'
848
+ pat = r'.*[\w\s]=\s*'+getname(encl)+r'\('+getname(fobj)
849
+ mod = getname(getmodule(encl))
850
+ #HACK: get file containing 'outer' function; is func there?
851
+ lines,_ = findsource(encl)
852
+ candidate = [line for line in lines if getname(encl) in line and \
853
+ re.match(pat, line)]
854
+ if not candidate:
855
+ mod = getname(getmodule(fobj))
856
+ #HACK: get file containing 'inner' function; is func there?
857
+ lines,_ = findsource(fobj)
858
+ candidate = [line for line in lines \
859
+ if getname(fobj) in line and re.match(pat, line)]
860
+ if not len(candidate): raise TypeError('import could not be found')
861
+ candidate = candidate[-1]
862
+ name = candidate.split('=',1)[0].split()[-1].strip()
863
+ src = _getimport(mod, name, alias=alias, builtin=builtin)
864
+ func_vars[name] = src
865
+ if not func_vars:
866
+ name = outermost(func)
867
+ mod = getname(getmodule(name))
868
+ if not mod or name is func: # then it can be handled by getimport
869
+ name = getname(func, force=True) #XXX: better key?
870
+ src = getimport(func, alias=alias, builtin=builtin)
871
+ else:
872
+ lines,_ = findsource(name)
873
+ # pattern: 'func = enclosing('
874
+ candidate = [line for line in lines if getname(name) in line and \
875
+ re.match(r'.*[\w\s]=\s*'+getname(name)+r'\(', line)]
876
+ if not len(candidate): raise TypeError('import could not be found')
877
+ candidate = candidate[-1]
878
+ name = candidate.split('=',1)[0].split()[-1].strip()
879
+ src = _getimport(mod, name, alias=alias, builtin=builtin)
880
+ func_vars[name] = src
881
+ return func_vars
882
+
883
+ #XXX: should be able to use __qualname__
884
+ def _closuredsource(func, alias=''):
885
+ """get source code for closured objects; return a dict of 'name'
886
+ and 'code blocks'"""
887
+ #FIXME: this entire function is a messy messy HACK
888
+ # - pollutes global namespace
889
+ # - fails if name of freevars are reused
890
+ # - can unnecessarily duplicate function code
891
+ from .detect import freevars
892
+ free_vars = freevars(func)
893
+ func_vars = {}
894
+ # split into 'funcs' and 'non-funcs'
895
+ for name,obj in list(free_vars.items()):
896
+ if not isfunction(obj):
897
+ # get source for 'non-funcs'
898
+ free_vars[name] = getsource(obj, force=True, alias=name)
899
+ continue
900
+ # get source for 'funcs'
901
+ fobj = free_vars.pop(name)
902
+ src = getsource(fobj, alias) # DO NOT include dependencies
903
+ # if source doesn't start with '@', use name as the alias
904
+ if not src.lstrip().startswith('@'): #FIXME: 'enclose' in dummy;
905
+ src = importable(fobj,alias=name)# wrong ref 'name'
906
+ org = getsource(func, alias, enclosing=False, lstrip=True)
907
+ src = (src, org) # undecorated first, then target
908
+ else: #NOTE: reproduces the code!
909
+ org = getsource(func, enclosing=True, lstrip=False)
910
+ src = importable(fobj, alias, source=True) # include dependencies
911
+ src = (org, src) # target first, then decorated
912
+ func_vars[name] = src
913
+ src = ''.join(free_vars.values())
914
+ if not func_vars: #FIXME: 'enclose' in dummy; wrong ref 'name'
915
+ org = getsource(func, alias, force=True, enclosing=False, lstrip=True)
916
+ src = (src, org) # variables first, then target
917
+ else:
918
+ src = (src, None) # just variables (better '' instead of None?)
919
+ func_vars[None] = src
920
+ # FIXME: remove duplicates (however, order is important...)
921
+ return func_vars
922
+
923
+ def importable(obj, alias='', source=None, builtin=True):
924
+ """get an importable string (i.e. source code or the import string)
925
+ for the given object, including any required objects from the enclosing
926
+ and global scope
927
+
928
+ This function will attempt to discover the name of the object, or the repr
929
+ of the object, or the source code for the object. To attempt to force
930
+ discovery of the source code, use source=True, to attempt to force the
931
+ use of an import, use source=False; otherwise an import will be sought
932
+ for objects not defined in __main__. The intent is to build a string
933
+ that can be imported from a python file.
934
+
935
+ obj is the object to inspect. If alias is provided, then rename the
936
+ object with the given alias. If builtin=True, then force an import for
937
+ builtins where possible.
938
+ """
939
+ #NOTE: we always 'force', and 'lstrip' as necessary
940
+ #NOTE: for 'enclosing', use importable(outermost(obj))
941
+ if source is None:
942
+ source = True if isfrommain(obj) else False
943
+ elif builtin and isbuiltin(obj):
944
+ source = False
945
+ tried_source = tried_import = False
946
+ while True:
947
+ if not source: # we want an import
948
+ try:
949
+ if _isinstance(obj): # for instances, punt to _importable
950
+ return _importable(obj, alias, source=False, builtin=builtin)
951
+ src = _closuredimport(obj, alias=alias, builtin=builtin)
952
+ if len(src) == 0:
953
+ raise NotImplementedError('not implemented')
954
+ if len(src) > 1:
955
+ raise NotImplementedError('not implemented')
956
+ return list(src.values())[0]
957
+ except Exception:
958
+ if tried_source: raise
959
+ tried_import = True
960
+ # we want the source
961
+ try:
962
+ src = _closuredsource(obj, alias=alias)
963
+ if len(src) == 0:
964
+ raise NotImplementedError('not implemented')
965
+ # groan... an inline code stitcher
966
+ def _code_stitcher(block):
967
+ "stitch together the strings in tuple 'block'"
968
+ if block[0] and block[-1]: block = '\n'.join(block)
969
+ elif block[0]: block = block[0]
970
+ elif block[-1]: block = block[-1]
971
+ else: block = ''
972
+ return block
973
+ # get free_vars first
974
+ _src = _code_stitcher(src.pop(None))
975
+ _src = [_src] if _src else []
976
+ # get func_vars
977
+ for xxx in src.values():
978
+ xxx = _code_stitcher(xxx)
979
+ if xxx: _src.append(xxx)
980
+ # make a single source string
981
+ if not len(_src):
982
+ src = ''
983
+ elif len(_src) == 1:
984
+ src = _src[0]
985
+ else:
986
+ src = '\n'.join(_src)
987
+ # get source code of objects referred to by obj in global scope
988
+ from .detect import globalvars
989
+ obj = globalvars(obj) #XXX: don't worry about alias? recurse? etc?
990
+ obj = list(getsource(_obj,name,force=True) for (name,_obj) in obj.items() if not isbuiltin(_obj))
991
+ obj = '\n'.join(obj) if obj else ''
992
+ # combine all referred-to source (global then enclosing)
993
+ if not obj: return src
994
+ if not src: return obj
995
+ return obj + src
996
+ except Exception:
997
+ if tried_import: raise
998
+ tried_source = True
999
+ source = not source
1000
+ # should never get here
1001
+ return
1002
+
1003
+
1004
+ # backward compatibility
1005
+ def getimportable(obj, alias='', byname=True, explicit=False):
1006
+ return importable(obj,alias,source=(not byname),builtin=explicit)
1007
+ #return outdent(_importable(obj,alias,source=(not byname),builtin=explicit))
1008
+ def likely_import(obj, passive=False, explicit=False):
1009
+ return getimport(obj, verify=(not passive), builtin=explicit)
1010
+ def _likely_import(first, last, passive=False, explicit=True):
1011
+ return _getimport(first, last, verify=(not passive), builtin=explicit)
1012
+ _get_name = getname
1013
+ getblocks_from_history = getblocks
1014
+
1015
+
1016
+
1017
+ # EOF
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dill/temp.py ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ #
3
+ # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
4
+ # Copyright (c) 2008-2016 California Institute of Technology.
5
+ # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
6
+ # License: 3-clause BSD. The full license text is available at:
7
+ # - https://github.com/uqfoundation/dill/blob/master/LICENSE
8
+ """
9
+ Methods for serialized objects (or source code) stored in temporary files
10
+ and file-like objects.
11
+ """
12
+ #XXX: better instead to have functions write to any given file-like object ?
13
+ #XXX: currently, all file-like objects are created by the function...
14
+
15
+ __all__ = ['dump_source', 'dump', 'dumpIO_source', 'dumpIO',\
16
+ 'load_source', 'load', 'loadIO_source', 'loadIO',\
17
+ 'capture']
18
+
19
+ import contextlib
20
+
21
+
22
+ @contextlib.contextmanager
23
+ def capture(stream='stdout'):
24
+ """builds a context that temporarily replaces the given stream name
25
+
26
+ >>> with capture('stdout') as out:
27
+ ... print ("foo!")
28
+ ...
29
+ >>> print (out.getvalue())
30
+ foo!
31
+
32
+ """
33
+ import sys
34
+ from io import StringIO
35
+ orig = getattr(sys, stream)
36
+ setattr(sys, stream, StringIO())
37
+ try:
38
+ yield getattr(sys, stream)
39
+ finally:
40
+ setattr(sys, stream, orig)
41
+
42
+
43
+ def b(x): # deal with b'foo' versus 'foo'
44
+ import codecs
45
+ return codecs.latin_1_encode(x)[0]
46
+
47
+ def load_source(file, **kwds):
48
+ """load an object that was stored with dill.temp.dump_source
49
+
50
+ file: filehandle
51
+ alias: string name of stored object
52
+ mode: mode to open the file, one of: {'r', 'rb'}
53
+
54
+ >>> f = lambda x: x**2
55
+ >>> pyfile = dill.temp.dump_source(f, alias='_f')
56
+ >>> _f = dill.temp.load_source(pyfile)
57
+ >>> _f(4)
58
+ 16
59
+ """
60
+ alias = kwds.pop('alias', None)
61
+ mode = kwds.pop('mode', 'r')
62
+ fname = getattr(file, 'name', file) # fname=file.name or fname=file (if str)
63
+ source = open(fname, mode=mode, **kwds).read()
64
+ if not alias:
65
+ tag = source.strip().splitlines()[-1].split()
66
+ if tag[0] != '#NAME:':
67
+ stub = source.splitlines()[0]
68
+ raise IOError("unknown name for code: %s" % stub)
69
+ alias = tag[-1]
70
+ local = {}
71
+ exec(source, local)
72
+ _ = eval("%s" % alias, local)
73
+ return _
74
+
75
+ def dump_source(object, **kwds):
76
+ """write object source to a NamedTemporaryFile (instead of dill.dump)
77
+ Loads with "import" or "dill.temp.load_source". Returns the filehandle.
78
+
79
+ >>> f = lambda x: x**2
80
+ >>> pyfile = dill.temp.dump_source(f, alias='_f')
81
+ >>> _f = dill.temp.load_source(pyfile)
82
+ >>> _f(4)
83
+ 16
84
+
85
+ >>> f = lambda x: x**2
86
+ >>> pyfile = dill.temp.dump_source(f, dir='.')
87
+ >>> modulename = os.path.basename(pyfile.name).split('.py')[0]
88
+ >>> exec('from %s import f as _f' % modulename)
89
+ >>> _f(4)
90
+ 16
91
+
92
+ Optional kwds:
93
+ If 'alias' is specified, the object will be renamed to the given string.
94
+
95
+ If 'prefix' is specified, the file name will begin with that prefix,
96
+ otherwise a default prefix is used.
97
+
98
+ If 'dir' is specified, the file will be created in that directory,
99
+ otherwise a default directory is used.
100
+
101
+ If 'text' is specified and true, the file is opened in text
102
+ mode. Else (the default) the file is opened in binary mode. On
103
+ some operating systems, this makes no difference.
104
+
105
+ NOTE: Keep the return value for as long as you want your file to exist !
106
+ """ #XXX: write a "load_source"?
107
+ from .source import importable, getname
108
+ import tempfile
109
+ kwds.setdefault('delete', True)
110
+ kwds.pop('suffix', '') # this is *always* '.py'
111
+ alias = kwds.pop('alias', '') #XXX: include an alias so a name is known
112
+ name = str(alias) or getname(object)
113
+ name = "\n#NAME: %s\n" % name
114
+ #XXX: assumes kwds['dir'] is writable and on $PYTHONPATH
115
+ file = tempfile.NamedTemporaryFile(suffix='.py', **kwds)
116
+ file.write(b(''.join([importable(object, alias=alias),name])))
117
+ file.flush()
118
+ return file
119
+
120
+ def load(file, **kwds):
121
+ """load an object that was stored with dill.temp.dump
122
+
123
+ file: filehandle
124
+ mode: mode to open the file, one of: {'r', 'rb'}
125
+
126
+ >>> dumpfile = dill.temp.dump([1, 2, 3, 4, 5])
127
+ >>> dill.temp.load(dumpfile)
128
+ [1, 2, 3, 4, 5]
129
+ """
130
+ import dill as pickle
131
+ mode = kwds.pop('mode', 'rb')
132
+ name = getattr(file, 'name', file) # name=file.name or name=file (if str)
133
+ return pickle.load(open(name, mode=mode, **kwds))
134
+
135
+ def dump(object, **kwds):
136
+ """dill.dump of object to a NamedTemporaryFile.
137
+ Loads with "dill.temp.load". Returns the filehandle.
138
+
139
+ >>> dumpfile = dill.temp.dump([1, 2, 3, 4, 5])
140
+ >>> dill.temp.load(dumpfile)
141
+ [1, 2, 3, 4, 5]
142
+
143
+ Optional kwds:
144
+ If 'suffix' is specified, the file name will end with that suffix,
145
+ otherwise there will be no suffix.
146
+
147
+ If 'prefix' is specified, the file name will begin with that prefix,
148
+ otherwise a default prefix is used.
149
+
150
+ If 'dir' is specified, the file will be created in that directory,
151
+ otherwise a default directory is used.
152
+
153
+ If 'text' is specified and true, the file is opened in text
154
+ mode. Else (the default) the file is opened in binary mode. On
155
+ some operating systems, this makes no difference.
156
+
157
+ NOTE: Keep the return value for as long as you want your file to exist !
158
+ """
159
+ import dill as pickle
160
+ import tempfile
161
+ kwds.setdefault('delete', True)
162
+ file = tempfile.NamedTemporaryFile(**kwds)
163
+ pickle.dump(object, file)
164
+ file.flush()
165
+ return file
166
+
167
+ def loadIO(buffer, **kwds):
168
+ """load an object that was stored with dill.temp.dumpIO
169
+
170
+ buffer: buffer object
171
+
172
+ >>> dumpfile = dill.temp.dumpIO([1, 2, 3, 4, 5])
173
+ >>> dill.temp.loadIO(dumpfile)
174
+ [1, 2, 3, 4, 5]
175
+ """
176
+ import dill as pickle
177
+ from io import BytesIO as StringIO
178
+ value = getattr(buffer, 'getvalue', buffer) # value or buffer.getvalue
179
+ if value != buffer: value = value() # buffer.getvalue()
180
+ return pickle.load(StringIO(value))
181
+
182
+ def dumpIO(object, **kwds):
183
+ """dill.dump of object to a buffer.
184
+ Loads with "dill.temp.loadIO". Returns the buffer object.
185
+
186
+ >>> dumpfile = dill.temp.dumpIO([1, 2, 3, 4, 5])
187
+ >>> dill.temp.loadIO(dumpfile)
188
+ [1, 2, 3, 4, 5]
189
+ """
190
+ import dill as pickle
191
+ from io import BytesIO as StringIO
192
+ file = StringIO()
193
+ pickle.dump(object, file)
194
+ file.flush()
195
+ return file
196
+
197
+ def loadIO_source(buffer, **kwds):
198
+ """load an object that was stored with dill.temp.dumpIO_source
199
+
200
+ buffer: buffer object
201
+ alias: string name of stored object
202
+
203
+ >>> f = lambda x:x**2
204
+ >>> pyfile = dill.temp.dumpIO_source(f, alias='_f')
205
+ >>> _f = dill.temp.loadIO_source(pyfile)
206
+ >>> _f(4)
207
+ 16
208
+ """
209
+ alias = kwds.pop('alias', None)
210
+ source = getattr(buffer, 'getvalue', buffer) # source or buffer.getvalue
211
+ if source != buffer: source = source() # buffer.getvalue()
212
+ source = source.decode() # buffer to string
213
+ if not alias:
214
+ tag = source.strip().splitlines()[-1].split()
215
+ if tag[0] != '#NAME:':
216
+ stub = source.splitlines()[0]
217
+ raise IOError("unknown name for code: %s" % stub)
218
+ alias = tag[-1]
219
+ local = {}
220
+ exec(source, local)
221
+ _ = eval("%s" % alias, local)
222
+ return _
223
+
224
+ def dumpIO_source(object, **kwds):
225
+ """write object source to a buffer (instead of dill.dump)
226
+ Loads by with dill.temp.loadIO_source. Returns the buffer object.
227
+
228
+ >>> f = lambda x:x**2
229
+ >>> pyfile = dill.temp.dumpIO_source(f, alias='_f')
230
+ >>> _f = dill.temp.loadIO_source(pyfile)
231
+ >>> _f(4)
232
+ 16
233
+
234
+ Optional kwds:
235
+ If 'alias' is specified, the object will be renamed to the given string.
236
+ """
237
+ from .source import importable, getname
238
+ from io import BytesIO as StringIO
239
+ alias = kwds.pop('alias', '') #XXX: include an alias so a name is known
240
+ name = str(alias) or getname(object)
241
+ name = "\n#NAME: %s\n" % name
242
+ #XXX: assumes kwds['dir'] is writable and on $PYTHONPATH
243
+ file = StringIO()
244
+ file.write(b(''.join([importable(object, alias=alias),name])))
245
+ file.flush()
246
+ return file
247
+
248
+
249
+ del contextlib
250
+
251
+
252
+ # EOF
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__init__.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # flake8: noqa
2
+ # Copyright 2020 The HuggingFace Evaluate Authors and the TensorFlow Datasets Authors.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # Lint as: python3
17
+ # pylint: enable=line-too-long
18
+ # pylint: disable=g-import-not-at-top,g-bad-import-order,wrong-import-position
19
+
20
+ __version__ = "0.4.6"
21
+
22
+ from packaging import version
23
+
24
+
25
+ SCRIPTS_VERSION = "main" if version.parse(__version__).is_devrelease else __version__
26
+
27
+ del version
28
+
29
+ from .evaluation_suite import EvaluationSuite
30
+ from .evaluator import (
31
+ AudioClassificationEvaluator,
32
+ AutomaticSpeechRecognitionEvaluator,
33
+ Evaluator,
34
+ ImageClassificationEvaluator,
35
+ QuestionAnsweringEvaluator,
36
+ SummarizationEvaluator,
37
+ Text2TextGenerationEvaluator,
38
+ TextClassificationEvaluator,
39
+ TextGenerationEvaluator,
40
+ TokenClassificationEvaluator,
41
+ TranslationEvaluator,
42
+ evaluator,
43
+ )
44
+ from .hub import push_to_hub
45
+ from .info import ComparisonInfo, EvaluationModuleInfo, MeasurementInfo, MetricInfo
46
+ from .inspect import inspect_evaluation_module, list_evaluation_modules
47
+ from .loading import load
48
+ from .module import CombinedEvaluations, Comparison, EvaluationModule, Measurement, Metric, combine
49
+ from .saving import save
50
+ from .utils import *
51
+ from .utils import gradio, logging
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/config.py ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import importlib
2
+ import os
3
+ import platform
4
+ from pathlib import Path
5
+
6
+ from packaging import version
7
+
8
+ from .utils.logging import get_logger
9
+
10
+
11
+ logger = get_logger(__name__)
12
+
13
+
14
+ # Metrics
15
+ S3_METRICS_BUCKET_PREFIX = "https://s3.amazonaws.com/datasets.huggingface.co/datasets/metrics"
16
+ CLOUDFRONT_METRICS_DISTRIB_PREFIX = "https://cdn-datasets.huggingface.co/datasets/metric"
17
+ REPO_METRICS_URL = "https://raw.githubusercontent.com/huggingface/evaluate/{revision}/metrics/{path}/{name}"
18
+ REPO_MEASUREMENTS_URL = "https://raw.githubusercontent.com/huggingface/evaluate/{revision}/measurements/{path}/{name}"
19
+ REPO_COMPARISONS_URL = "https://raw.githubusercontent.com/huggingface/evaluate/{revision}/comparisons/{path}/{name}"
20
+
21
+ # Evaluation module types
22
+ EVALUATION_MODULE_TYPES = ["metric", "comparison", "measurement"]
23
+
24
+ # Hub
25
+ HF_ENDPOINT = os.environ.get("HF_ENDPOINT", "https://huggingface.co")
26
+ HF_LIST_ENDPOINT = HF_ENDPOINT + "/api/spaces?filter={type}"
27
+ HUB_EVALUATE_URL = HF_ENDPOINT + "/spaces/{path}/resolve/{revision}/{name}"
28
+ HUB_DEFAULT_VERSION = "main"
29
+
30
+ PY_VERSION = version.parse(platform.python_version())
31
+
32
+ if PY_VERSION < version.parse("3.8"):
33
+ import importlib_metadata
34
+ else:
35
+ import importlib.metadata as importlib_metadata
36
+
37
+ # General environment variables accepted values for booleans
38
+ ENV_VARS_TRUE_VALUES = {"1", "ON", "YES", "TRUE"}
39
+ ENV_VARS_TRUE_AND_AUTO_VALUES = ENV_VARS_TRUE_VALUES.union({"AUTO"})
40
+
41
+
42
+ # Imports
43
+ PANDAS_VERSION = version.parse(importlib_metadata.version("pandas"))
44
+ PYARROW_VERSION = version.parse(importlib_metadata.version("pyarrow"))
45
+
46
+ USE_TF = os.environ.get("USE_TF", "AUTO").upper()
47
+ USE_TORCH = os.environ.get("USE_TORCH", "AUTO").upper()
48
+ USE_JAX = os.environ.get("USE_JAX", "AUTO").upper()
49
+
50
+ TORCH_VERSION = "N/A"
51
+ TORCH_AVAILABLE = False
52
+
53
+ if USE_TORCH in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TF not in ENV_VARS_TRUE_VALUES:
54
+ TORCH_AVAILABLE = importlib.util.find_spec("torch") is not None
55
+ if TORCH_AVAILABLE:
56
+ try:
57
+ TORCH_VERSION = version.parse(importlib_metadata.version("torch"))
58
+ logger.info(f"PyTorch version {TORCH_VERSION} available.")
59
+ except importlib_metadata.PackageNotFoundError:
60
+ pass
61
+ else:
62
+ logger.info("Disabling PyTorch because USE_TF is set")
63
+
64
+ TF_VERSION = "N/A"
65
+ TF_AVAILABLE = False
66
+
67
+ if USE_TF in ENV_VARS_TRUE_AND_AUTO_VALUES and USE_TORCH not in ENV_VARS_TRUE_VALUES:
68
+ TF_AVAILABLE = importlib.util.find_spec("tensorflow") is not None
69
+ if TF_AVAILABLE:
70
+ # For the metadata, we have to look for both tensorflow and tensorflow-cpu
71
+ for package in [
72
+ "tensorflow",
73
+ "tensorflow-cpu",
74
+ "tensorflow-gpu",
75
+ "tf-nightly",
76
+ "tf-nightly-cpu",
77
+ "tf-nightly-gpu",
78
+ "intel-tensorflow",
79
+ "tensorflow-rocm",
80
+ "tensorflow-macos",
81
+ ]:
82
+ try:
83
+ TF_VERSION = version.parse(importlib_metadata.version(package))
84
+ except importlib_metadata.PackageNotFoundError:
85
+ continue
86
+ else:
87
+ break
88
+ else:
89
+ TF_AVAILABLE = False
90
+ if TF_AVAILABLE:
91
+ if TF_VERSION.major < 2:
92
+ logger.info(f"TensorFlow found but with version {TF_VERSION}. `datasets` requires version 2 minimum.")
93
+ TF_AVAILABLE = False
94
+ else:
95
+ logger.info(f"TensorFlow version {TF_VERSION} available.")
96
+ else:
97
+ logger.info("Disabling Tensorflow because USE_TORCH is set")
98
+
99
+
100
+ JAX_VERSION = "N/A"
101
+ JAX_AVAILABLE = False
102
+
103
+ if USE_JAX in ENV_VARS_TRUE_AND_AUTO_VALUES:
104
+ JAX_AVAILABLE = importlib.util.find_spec("jax") is not None
105
+ if JAX_AVAILABLE:
106
+ try:
107
+ JAX_VERSION = version.parse(importlib_metadata.version("jax"))
108
+ logger.info(f"JAX version {JAX_VERSION} available.")
109
+ except importlib_metadata.PackageNotFoundError:
110
+ pass
111
+ else:
112
+ logger.info("Disabling JAX because USE_JAX is set to False")
113
+
114
+
115
+ # Cache location
116
+ DEFAULT_XDG_CACHE_HOME = "~/.cache"
117
+ XDG_CACHE_HOME = os.getenv("XDG_CACHE_HOME", DEFAULT_XDG_CACHE_HOME)
118
+ DEFAULT_HF_CACHE_HOME = os.path.join(XDG_CACHE_HOME, "huggingface")
119
+ HF_CACHE_HOME = os.path.expanduser(os.getenv("HF_HOME", DEFAULT_HF_CACHE_HOME))
120
+
121
+ DEFAULT_HF_EVALUATE_CACHE = os.path.join(HF_CACHE_HOME, "evaluate")
122
+ HF_EVALUATE_CACHE = Path(os.getenv("HF_EVALUATE_CACHE", DEFAULT_HF_EVALUATE_CACHE))
123
+
124
+ DEFAULT_HF_METRICS_CACHE = os.path.join(HF_CACHE_HOME, "metrics")
125
+ HF_METRICS_CACHE = Path(os.getenv("HF_METRICS_CACHE", DEFAULT_HF_METRICS_CACHE))
126
+
127
+ DEFAULT_HF_MODULES_CACHE = os.path.join(HF_CACHE_HOME, "modules")
128
+ HF_MODULES_CACHE = Path(os.getenv("HF_MODULES_CACHE", DEFAULT_HF_MODULES_CACHE))
129
+
130
+ DOWNLOADED_DATASETS_DIR = "downloads"
131
+ DEFAULT_DOWNLOADED_EVALUATE_PATH = os.path.join(HF_EVALUATE_CACHE, DOWNLOADED_DATASETS_DIR)
132
+ DOWNLOADED_EVALUATE_PATH = Path(os.getenv("HF_DATASETS_DOWNLOADED_EVALUATE_PATH", DEFAULT_DOWNLOADED_EVALUATE_PATH))
133
+
134
+ EXTRACTED_EVALUATE_DIR = "extracted"
135
+ DEFAULT_EXTRACTED_EVALUATE_PATH = os.path.join(DEFAULT_DOWNLOADED_EVALUATE_PATH, EXTRACTED_EVALUATE_DIR)
136
+ EXTRACTED_EVALUATE_PATH = Path(os.getenv("HF_DATASETS_EXTRACTED_EVALUATE_PATH", DEFAULT_EXTRACTED_EVALUATE_PATH))
137
+
138
+ # Download count for the website
139
+ HF_UPDATE_DOWNLOAD_COUNTS = (
140
+ os.environ.get("HF_UPDATE_DOWNLOAD_COUNTS", "AUTO").upper() in ENV_VARS_TRUE_AND_AUTO_VALUES
141
+ )
142
+
143
+ # Offline mode
144
+ HF_EVALUATE_OFFLINE = os.environ.get("HF_EVALUATE_OFFLINE", "AUTO").upper() in ENV_VARS_TRUE_VALUES
145
+
146
+
147
+ # File names
148
+ LICENSE_FILENAME = "LICENSE"
149
+ METRIC_INFO_FILENAME = "metric_info.json"
150
+ DATASETDICT_JSON_FILENAME = "dataset_dict.json"
151
+
152
+ MODULE_NAME_FOR_DYNAMIC_MODULES = "evaluate_modules"
153
+
154
+ HF_HUB_ALLOWED_TASKS = [
155
+ "image-classification",
156
+ "translation",
157
+ "image-segmentation",
158
+ "fill-mask",
159
+ "automatic-speech-recognition",
160
+ "token-classification",
161
+ "sentence-similarity",
162
+ "audio-classification",
163
+ "question-answering",
164
+ "summarization",
165
+ "zero-shot-classification",
166
+ "table-to-text",
167
+ "feature-extraction",
168
+ "other",
169
+ "multiple-choice",
170
+ "text-classification",
171
+ "text-to-image",
172
+ "text2text-generation",
173
+ "zero-shot-image-classification",
174
+ "tabular-classification",
175
+ "tabular-regression",
176
+ "image-to-image",
177
+ "tabular-to-text",
178
+ "unconditional-image-generation",
179
+ "text-retrieval",
180
+ "text-to-speech",
181
+ "object-detection",
182
+ "audio-to-audio",
183
+ "text-generation",
184
+ "conversational",
185
+ "table-question-answering",
186
+ "visual-question-answering",
187
+ "image-to-text",
188
+ "reinforcement-learning",
189
+ "voice-activity-detection",
190
+ "time-series-forecasting",
191
+ "document-question-answering",
192
+ ]
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/hub.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict
2
+
3
+ import requests
4
+ from huggingface_hub import dataset_info, model_info
5
+ from huggingface_hub.repocard import metadata_update
6
+
7
+ from .config import HF_HUB_ALLOWED_TASKS
8
+ from .utils.logging import get_logger
9
+
10
+
11
+ logger = get_logger(__name__)
12
+
13
+
14
+ def push_to_hub(
15
+ model_id: str,
16
+ task_type: str,
17
+ dataset_type: str,
18
+ dataset_name: str,
19
+ metric_type: str,
20
+ metric_name: str,
21
+ metric_value: float,
22
+ task_name: str = None,
23
+ dataset_config: str = None,
24
+ dataset_split: str = None,
25
+ dataset_revision: str = None,
26
+ dataset_args: Dict[str, int] = None,
27
+ metric_config: str = None,
28
+ metric_args: Dict[str, int] = None,
29
+ overwrite: bool = False,
30
+ ):
31
+ r"""
32
+ Pushes the result of a metric to the metadata of a model repository in the Hub.
33
+
34
+ Args:
35
+ model_id (`str`):
36
+ Model id from https://hf.co/models.
37
+ task_type (`str`):
38
+ Task id, refer to the [Hub allowed tasks](https://github.com/huggingface/evaluate/blob/main/src/evaluate/config.py#L154) for allowed values.
39
+ dataset_type (`str`):
40
+ Dataset id from https://hf.co/datasets.
41
+ dataset_name (`str`):
42
+ Pretty name for the dataset.
43
+ metric_type (`str`):
44
+ Metric id from https://hf.co/metrics.
45
+ metric_name (`str`):
46
+ Pretty name for the metric.
47
+ metric_value (`float`):
48
+ Computed metric value.
49
+ task_name (`str`, *optional*):
50
+ Pretty name for the task.
51
+ dataset_config (`str`, *optional*):
52
+ Dataset configuration used in [`~datasets.load_dataset`].
53
+ See [`~datasets.load_dataset`] for more info.
54
+ dataset_split (`str`, *optional*):
55
+ Name of split used for metric computation.
56
+ dataset_revision (`str`, *optional*):
57
+ Git hash for the specific version of the dataset.
58
+ dataset_args (`dict[str, int]`, *optional*):
59
+ Additional arguments passed to [`~datasets.load_dataset`].
60
+ metric_config (`str`, *optional*):
61
+ Configuration for the metric (e.g. the GLUE metric has a configuration for each subset).
62
+ metric_args (`dict[str, int]`, *optional*):
63
+ Arguments passed during [`~evaluate.EvaluationModule.compute`].
64
+ overwrite (`bool`, *optional*, defaults to `False`):
65
+ If set to `True` an existing metric field can be overwritten, otherwise
66
+ attempting to overwrite any existing fields will cause an error.
67
+
68
+ Example:
69
+
70
+ ```python
71
+ >>> push_to_hub(
72
+ ... model_id="huggingface/gpt2-wikitext2",
73
+ ... metric_value=0.5
74
+ ... metric_type="bleu",
75
+ ... metric_name="BLEU",
76
+ ... dataset_name="WikiText",
77
+ ... dataset_type="wikitext",
78
+ ... dataset_split="test",
79
+ ... task_type="text-generation",
80
+ ... task_name="Text Generation"
81
+ ... )
82
+ ```"""
83
+ if task_type not in HF_HUB_ALLOWED_TASKS:
84
+ raise ValueError(f"Task type not supported. Task has to be one of {HF_HUB_ALLOWED_TASKS}")
85
+
86
+ try:
87
+ dataset_info(dataset_type)
88
+ except requests.exceptions.HTTPError:
89
+ logger.warning(f"Dataset {dataset_type} not found on the Hub at hf.co/datasets/{dataset_type}")
90
+
91
+ try:
92
+ model_info(model_id)
93
+ except requests.exceptions.HTTPError:
94
+ raise ValueError(f"Model {model_id} not found on the Hub at hf.co/{model_id}")
95
+
96
+ result = {
97
+ "task": {
98
+ "type": task_type,
99
+ },
100
+ "dataset": {
101
+ "type": dataset_type,
102
+ "name": dataset_name,
103
+ },
104
+ "metrics": [
105
+ {
106
+ "type": metric_type,
107
+ "value": metric_value,
108
+ },
109
+ ],
110
+ }
111
+
112
+ if dataset_config is not None:
113
+ result["dataset"]["config"] = dataset_config
114
+ if dataset_split is not None:
115
+ result["dataset"]["split"] = dataset_split
116
+ if dataset_revision is not None:
117
+ result["dataset"]["revision"] = dataset_revision
118
+ if dataset_args is not None:
119
+ result["dataset"]["args"] = dataset_args
120
+
121
+ if task_name is not None:
122
+ result["task"]["name"] = task_name
123
+
124
+ if metric_name is not None:
125
+ result["metrics"][0]["name"] = metric_name
126
+ if metric_config is not None:
127
+ result["metrics"][0]["config"] = metric_config
128
+ if metric_args is not None:
129
+ result["metrics"][0]["args"] = metric_args
130
+
131
+ metadata = {"model-index": [{"results": [result]}]}
132
+
133
+ return metadata_update(repo_id=model_id, metadata=metadata, overwrite=overwrite)
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/info.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ # Lint as: python3
16
+ """ EvaluationModuleInfo records information we know about a dataset and a metric.
17
+ """
18
+
19
+ import dataclasses
20
+ import json
21
+ import os
22
+ from dataclasses import asdict, dataclass, field
23
+ from typing import List, Optional, Union
24
+
25
+ from datasets.features import Features, Value
26
+
27
+ from . import config
28
+ from .utils.logging import get_logger
29
+
30
+
31
+ logger = get_logger(__name__)
32
+
33
+
34
+ @dataclass
35
+ class EvaluationModuleInfo:
36
+ """Base class to store information about an evaluation used for `MetricInfo`, `ComparisonInfo`,
37
+ and `MeasurementInfo`.
38
+
39
+ `EvaluationModuleInfo` documents an evaluation, including its name, version, and features.
40
+ See the constructor arguments and properties for a full list.
41
+
42
+ Note: Not all fields are known on construction and may be updated later.
43
+ """
44
+
45
+ # Set in the dataset scripts
46
+ description: str
47
+ citation: str
48
+ features: Union[Features, List[Features]]
49
+ inputs_description: str = field(default_factory=str)
50
+ homepage: str = field(default_factory=str)
51
+ license: str = field(default_factory=str)
52
+ codebase_urls: List[str] = field(default_factory=list)
53
+ reference_urls: List[str] = field(default_factory=list)
54
+ streamable: bool = False
55
+ format: Optional[str] = None
56
+ module_type: str = "metric" # deprecate this in the future
57
+
58
+ # Set later by the builder
59
+ module_name: Optional[str] = None
60
+ config_name: Optional[str] = None
61
+ experiment_id: Optional[str] = None
62
+
63
+ def __post_init__(self):
64
+ if self.format is not None:
65
+ for key, value in self.features.items():
66
+ if not isinstance(value, Value):
67
+ raise ValueError(
68
+ f"When using 'numpy' format, all features should be a `datasets.Value` feature. "
69
+ f"Here {key} is an instance of {value.__class__.__name__}"
70
+ )
71
+
72
+ def write_to_directory(self, metric_info_dir):
73
+ """Write `EvaluationModuleInfo` as JSON to `metric_info_dir`.
74
+ Also save the license separately in LICENSE.
75
+
76
+ Args:
77
+ metric_info_dir (`str`):
78
+ The directory to save `metric_info_dir` to.
79
+
80
+ Example:
81
+
82
+ ```py
83
+ >>> my_metric.info.write_to_directory("/path/to/directory/")
84
+ ```
85
+ """
86
+ with open(os.path.join(metric_info_dir, config.METRIC_INFO_FILENAME), "w", encoding="utf-8") as f:
87
+ json.dump(asdict(self), f)
88
+
89
+ with open(os.path.join(metric_info_dir, config.LICENSE_FILENAME), "w", encoding="utf-8") as f:
90
+ f.write(self.license)
91
+
92
+ @classmethod
93
+ def from_directory(cls, metric_info_dir) -> "EvaluationModuleInfo":
94
+ """Create `EvaluationModuleInfo` from the JSON file in `metric_info_dir`.
95
+
96
+ Args:
97
+ metric_info_dir (`str`):
98
+ The directory containing the `metric_info` JSON file. This
99
+ should be the root directory of a specific metric version.
100
+
101
+ Example:
102
+
103
+ ```py
104
+ >>> my_metric = EvaluationModuleInfo.from_directory("/path/to/directory/")
105
+ ```
106
+ """
107
+ logger.info(f"Loading Metric info from {metric_info_dir}")
108
+ if not metric_info_dir:
109
+ raise ValueError("Calling EvaluationModuleInfo.from_directory() with undefined metric_info_dir.")
110
+
111
+ with open(os.path.join(metric_info_dir, config.METRIC_INFO_FILENAME), encoding="utf-8") as f:
112
+ metric_info_dict = json.load(f)
113
+ return cls.from_dict(metric_info_dict)
114
+
115
+ @classmethod
116
+ def from_dict(cls, metric_info_dict: dict) -> "EvaluationModuleInfo":
117
+ field_names = {f.name for f in dataclasses.fields(cls)}
118
+ return cls(**{k: v for k, v in metric_info_dict.items() if k in field_names})
119
+
120
+
121
+ @dataclass
122
+ class MetricInfo(EvaluationModuleInfo):
123
+ """Information about a metric.
124
+
125
+ `EvaluationModuleInfo` documents a metric, including its name, version, and features.
126
+ See the constructor arguments and properties for a full list.
127
+
128
+ Note: Not all fields are known on construction and may be updated later.
129
+ """
130
+
131
+ module_type: str = "metric"
132
+
133
+
134
+ @dataclass
135
+ class ComparisonInfo(EvaluationModuleInfo):
136
+ """Information about a comparison.
137
+
138
+ `EvaluationModuleInfo` documents a comparison, including its name, version, and features.
139
+ See the constructor arguments and properties for a full list.
140
+
141
+ Note: Not all fields are known on construction and may be updated later.
142
+ """
143
+
144
+ module_type: str = "comparison"
145
+
146
+
147
+ @dataclass
148
+ class MeasurementInfo(EvaluationModuleInfo):
149
+ """Information about a measurement.
150
+
151
+ `EvaluationModuleInfo` documents a measurement, including its name, version, and features.
152
+ See the constructor arguments and properties for a full list.
153
+
154
+ Note: Not all fields are known on construction and may be updated later.
155
+ """
156
+
157
+ module_type: str = "measurement"
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/loading.py ADDED
@@ -0,0 +1,771 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ # Lint as: python3
16
+ """Access datasets."""
17
+ import filecmp
18
+ import importlib
19
+ import inspect
20
+ import json
21
+ import os
22
+ import re
23
+ import shutil
24
+ import time
25
+ from dataclasses import dataclass
26
+ from pathlib import Path
27
+ from typing import List, Optional, Tuple, Type, Union
28
+ from urllib.parse import urlparse
29
+
30
+ from datasets import DownloadConfig, DownloadMode
31
+ from datasets.builder import DatasetBuilder
32
+ from datasets.packaged_modules import _EXTENSION_TO_MODULE, _hash_python_lines
33
+ from datasets.utils.filelock import FileLock
34
+ from datasets.utils.version import Version
35
+
36
+ from . import SCRIPTS_VERSION, config
37
+ from .module import EvaluationModule
38
+ from .utils.file_utils import (
39
+ cached_path,
40
+ head_hf_s3,
41
+ hf_hub_url,
42
+ init_hf_modules,
43
+ is_relative_path,
44
+ relative_to_absolute_path,
45
+ url_or_path_join,
46
+ )
47
+ from .utils.logging import get_logger
48
+
49
+
50
+ logger = get_logger(__name__)
51
+
52
+
53
+ ALL_ALLOWED_EXTENSIONS = list(_EXTENSION_TO_MODULE.keys()) + ["zip"]
54
+
55
+
56
+ def init_dynamic_modules(
57
+ name: str = config.MODULE_NAME_FOR_DYNAMIC_MODULES, hf_modules_cache: Optional[Union[Path, str]] = None
58
+ ):
59
+ """
60
+ Create a module with name `name` in which you can add dynamic modules
61
+ such as metrics or datasets. The module can be imported using its name.
62
+ The module is created in the HF_MODULE_CACHE directory by default (~/.cache/huggingface/modules) but it can
63
+ be overriden by specifying a path to another directory in `hf_modules_cache`.
64
+ """
65
+ hf_modules_cache = init_hf_modules(hf_modules_cache)
66
+ dynamic_modules_path = os.path.join(hf_modules_cache, name)
67
+ os.makedirs(dynamic_modules_path, exist_ok=True)
68
+ if not os.path.exists(os.path.join(dynamic_modules_path, "__init__.py")):
69
+ with open(os.path.join(dynamic_modules_path, "__init__.py"), "w"):
70
+ pass
71
+ return dynamic_modules_path
72
+
73
+
74
+ def import_main_class(module_path) -> Optional[Union[Type[DatasetBuilder], Type[EvaluationModule]]]:
75
+ """Import a module at module_path and return its main class, a Metric by default"""
76
+ module = importlib.import_module(module_path)
77
+ main_cls_type = EvaluationModule
78
+
79
+ # Find the main class in our imported module
80
+ module_main_cls = None
81
+ for name, obj in module.__dict__.items():
82
+ if isinstance(obj, type) and issubclass(obj, main_cls_type):
83
+ if inspect.isabstract(obj):
84
+ continue
85
+ module_main_cls = obj
86
+ break
87
+
88
+ return module_main_cls
89
+
90
+
91
+ def files_to_hash(file_paths: List[str]) -> str:
92
+ """
93
+ Convert a list of scripts or text files provided in file_paths into a hashed filename in a repeatable way.
94
+ """
95
+ # List all python files in directories if directories are supplied as part of external imports
96
+ to_use_files: List[Union[Path, str]] = []
97
+ for file_path in file_paths:
98
+ if os.path.isdir(file_path):
99
+ to_use_files.extend(list(Path(file_path).rglob("*.[pP][yY]")))
100
+ else:
101
+ to_use_files.append(file_path)
102
+
103
+ # Get the code from all these files
104
+ lines = []
105
+ for file_path in to_use_files:
106
+ with open(file_path, encoding="utf-8") as f:
107
+ lines.extend(f.readlines())
108
+ return _hash_python_lines(lines)
109
+
110
+
111
+ def convert_github_url(url_path: str) -> Tuple[str, Optional[str]]:
112
+ """Convert a link to a file on a github repo in a link to the raw github object."""
113
+ parsed = urlparse(url_path)
114
+ sub_directory = None
115
+ if parsed.scheme in ("http", "https", "s3") and parsed.netloc == "github.com":
116
+ if "blob" in url_path:
117
+ if not url_path.endswith(".py"):
118
+ raise ValueError(f"External import from github at {url_path} should point to a file ending with '.py'")
119
+ url_path = url_path.replace("blob", "raw") # Point to the raw file
120
+ else:
121
+ # Parse github url to point to zip
122
+ github_path = parsed.path[1:]
123
+ repo_info, branch = github_path.split("/tree/") if "/tree/" in github_path else (github_path, "master")
124
+ repo_owner, repo_name = repo_info.split("/")
125
+ url_path = f"https://github.com/{repo_owner}/{repo_name}/archive/{branch}.zip"
126
+ sub_directory = f"{repo_name}-{branch}"
127
+ return url_path, sub_directory
128
+
129
+
130
+ def increase_load_count(name: str, resource_type: str):
131
+ """Update the download count of a dataset or metric."""
132
+ if not config.HF_EVALUATE_OFFLINE and config.HF_UPDATE_DOWNLOAD_COUNTS:
133
+ try:
134
+ head_hf_s3(name, filename=name + ".py", dataset=(resource_type == "dataset"))
135
+ except Exception:
136
+ pass
137
+
138
+
139
+ def get_imports(file_path: str) -> Tuple[str, str, str, str]:
140
+ """Find whether we should import or clone additional files for a given processing script.
141
+ And list the import.
142
+
143
+ We allow:
144
+ - library dependencies,
145
+ - local dependencies and
146
+ - external dependencies whose url is specified with a comment starting from "# From:' followed by the raw url to a file, an archive or a github repository.
147
+ external dependencies will be downloaded (and extracted if needed in the dataset folder).
148
+ We also add an `__init__.py` to each sub-folder of a downloaded folder so the user can import from them in the script.
149
+
150
+ Note that only direct import in the dataset processing script will be handled
151
+ We don't recursively explore the additional import to download further files.
152
+
153
+ Example::
154
+
155
+ import tensorflow
156
+ import .c4_utils
157
+ import .clicr.dataset-code.build_json_dataset # From: https://raw.githubusercontent.com/clips/clicr/master/dataset-code/build_json_dataset
158
+ """
159
+ lines = []
160
+ with open(file_path, encoding="utf-8") as f:
161
+ lines.extend(f.readlines())
162
+
163
+ logger.debug(f"Checking {file_path} for additional imports.")
164
+ imports: List[Tuple[str, str, str, Optional[str]]] = []
165
+ is_in_docstring = False
166
+ for line in lines:
167
+ docstr_start_match = re.findall(r'[\s\S]*?"""[\s\S]*?', line)
168
+
169
+ if len(docstr_start_match) == 1:
170
+ # flip True <=> False only if doctstring
171
+ # starts at line without finishing
172
+ is_in_docstring = not is_in_docstring
173
+
174
+ if is_in_docstring:
175
+ # import statements in doctstrings should
176
+ # not be added as required dependencies
177
+ continue
178
+
179
+ match = re.match(r"^import\s+(\.?)([^\s\.]+)[^#\r\n]*(?:#\s+From:\s+)?([^\r\n]*)", line, flags=re.MULTILINE)
180
+ if match is None:
181
+ match = re.match(
182
+ r"^from\s+(\.?)([^\s\.]+)(?:[^\s]*)\s+import\s+[^#\r\n]*(?:#\s+From:\s+)?([^\r\n]*)",
183
+ line,
184
+ flags=re.MULTILINE,
185
+ )
186
+ if match is None:
187
+ continue
188
+ if match.group(1):
189
+ # The import starts with a '.', we will download the relevant file
190
+ if any(imp[1] == match.group(2) for imp in imports):
191
+ # We already have this import
192
+ continue
193
+ if match.group(3):
194
+ # The import has a comment with 'From:', we'll retrieve it from the given url
195
+ url_path = match.group(3)
196
+ url_path, sub_directory = convert_github_url(url_path)
197
+ imports.append(("external", match.group(2), url_path, sub_directory))
198
+ elif match.group(2):
199
+ # The import should be at the same place as the file
200
+ imports.append(("internal", match.group(2), match.group(2), None))
201
+ else:
202
+ if match.group(3):
203
+ # The import has a comment with `From: git+https:...`, asks user to pip install from git.
204
+ url_path = match.group(3)
205
+ imports.append(("library", match.group(2), url_path, None))
206
+ else:
207
+ imports.append(("library", match.group(2), match.group(2), None))
208
+
209
+ return imports
210
+
211
+
212
+ def _download_additional_modules(
213
+ name: str, base_path: str, imports: Tuple[str, str, str, str], download_config: Optional[DownloadConfig]
214
+ ) -> List[Tuple[str, str]]:
215
+ """
216
+ Download additional module for a module <name>.py at URL (or local path) <base_path>/<name>.py
217
+ The imports must have been parsed first using ``get_imports``.
218
+
219
+ If some modules need to be installed with pip, an error is raised showing how to install them.
220
+ This function return the list of downloaded modules as tuples (import_name, module_file_path).
221
+
222
+ The downloaded modules can then be moved into an importable directory with ``_copy_script_and_other_resources_in_importable_dir``.
223
+ """
224
+ local_imports = []
225
+ library_imports = []
226
+ download_config = download_config.copy()
227
+ if download_config.download_desc is None:
228
+ download_config.download_desc = "Downloading extra modules"
229
+ for import_type, import_name, import_path, sub_directory in imports:
230
+ if import_type == "library":
231
+ library_imports.append((import_name, import_path)) # Import from a library
232
+ continue
233
+
234
+ if import_name == name:
235
+ raise ValueError(
236
+ f"Error in the {name} script, importing relative {import_name} module "
237
+ f"but {import_name} is the name of the script. "
238
+ f"Please change relative import {import_name} to another name and add a '# From: URL_OR_PATH' "
239
+ f"comment pointing to the original relative import file path."
240
+ )
241
+ if import_type == "internal":
242
+ url_or_filename = url_or_path_join(base_path, import_path + ".py")
243
+ elif import_type == "external":
244
+ url_or_filename = import_path
245
+ else:
246
+ raise ValueError("Wrong import_type")
247
+
248
+ local_import_path = cached_path(
249
+ url_or_filename,
250
+ download_config=download_config,
251
+ )
252
+ if sub_directory is not None:
253
+ local_import_path = os.path.join(local_import_path, sub_directory)
254
+ local_imports.append((import_name, local_import_path))
255
+
256
+ # Check library imports
257
+ needs_to_be_installed = set()
258
+ for library_import_name, library_import_path in library_imports:
259
+ try:
260
+ lib = importlib.import_module(library_import_name) # noqa F841
261
+ except ImportError:
262
+ library_import_name = "scikit-learn" if library_import_name == "sklearn" else library_import_name
263
+ needs_to_be_installed.add((library_import_name, library_import_path))
264
+ if needs_to_be_installed:
265
+ raise ImportError(
266
+ f"To be able to use {name}, you need to install the following dependencies"
267
+ f"{[lib_name for lib_name, lib_path in needs_to_be_installed]} using 'pip install "
268
+ f"{' '.join([lib_path for lib_name, lib_path in needs_to_be_installed])}' for instance'"
269
+ )
270
+ return local_imports
271
+
272
+
273
+ def _copy_script_and_other_resources_in_importable_dir(
274
+ name: str,
275
+ importable_directory_path: str,
276
+ subdirectory_name: str,
277
+ original_local_path: str,
278
+ local_imports: List[Tuple[str, str]],
279
+ additional_files: List[Tuple[str, str]],
280
+ download_mode: Optional[DownloadMode],
281
+ ) -> str:
282
+ """Copy a script and its required imports to an importable directory
283
+
284
+ Args:
285
+ name (str): name of the resource to load
286
+ importable_directory_path (str): path to the loadable folder in the dynamic modules directory
287
+ subdirectory_name (str): name of the subdirectory in importable_directory_path in which to place the script
288
+ original_local_path (str): local path to the resource script
289
+ local_imports (List[Tuple[str, str]]): list of (destination_filename, import_file_to_copy)
290
+ additional_files (List[Tuple[str, str]]): list of (destination_filename, additional_file_to_copy)
291
+ download_mode (Optional[DownloadMode]): download mode
292
+
293
+ Return:
294
+ importable_local_file: path to an importable module with importlib.import_module
295
+ """
296
+
297
+ # Define a directory with a unique name in our dataset or metric folder
298
+ # path is: ./datasets|metrics/dataset|metric_name/hash_from_code/script.py
299
+ # we use a hash as subdirectory_name to be able to have multiple versions of a dataset/metric processing file together
300
+ importable_subdirectory = os.path.join(importable_directory_path, subdirectory_name)
301
+ importable_local_file = os.path.join(importable_subdirectory, name + ".py")
302
+
303
+ # Prevent parallel disk operations
304
+ lock_path = importable_directory_path + ".lock"
305
+ with FileLock(lock_path):
306
+ # Create main dataset/metrics folder if needed
307
+ if download_mode == DownloadMode.FORCE_REDOWNLOAD and os.path.exists(importable_directory_path):
308
+ shutil.rmtree(importable_directory_path)
309
+ os.makedirs(importable_directory_path, exist_ok=True)
310
+
311
+ # add an __init__ file to the main dataset folder if needed
312
+ init_file_path = os.path.join(importable_directory_path, "__init__.py")
313
+ if not os.path.exists(init_file_path):
314
+ with open(init_file_path, "w"):
315
+ pass
316
+
317
+ # Create hash dataset folder if needed
318
+ os.makedirs(importable_subdirectory, exist_ok=True)
319
+ # add an __init__ file to the hash dataset folder if needed
320
+ init_file_path = os.path.join(importable_subdirectory, "__init__.py")
321
+ if not os.path.exists(init_file_path):
322
+ with open(init_file_path, "w"):
323
+ pass
324
+
325
+ # Copy dataset.py file in hash folder if needed
326
+ if not os.path.exists(importable_local_file):
327
+ shutil.copyfile(original_local_path, importable_local_file)
328
+
329
+ # Record metadata associating original dataset path with local unique folder
330
+ meta_path = importable_local_file.split(".py")[0] + ".json"
331
+ if not os.path.exists(meta_path):
332
+ meta = {"original file path": original_local_path, "local file path": importable_local_file}
333
+ # the filename is *.py in our case, so better rename to filenam.json instead of filename.py.json
334
+ with open(meta_path, "w", encoding="utf-8") as meta_file:
335
+ json.dump(meta, meta_file)
336
+
337
+ # Copy all the additional imports
338
+ for import_name, import_path in local_imports:
339
+ if os.path.isfile(import_path):
340
+ full_path_local_import = os.path.join(importable_subdirectory, import_name + ".py")
341
+ if not os.path.exists(full_path_local_import):
342
+ shutil.copyfile(import_path, full_path_local_import)
343
+ elif os.path.isdir(import_path):
344
+ full_path_local_import = os.path.join(importable_subdirectory, import_name)
345
+ if not os.path.exists(full_path_local_import):
346
+ shutil.copytree(import_path, full_path_local_import)
347
+ else:
348
+ raise OSError(f"Error with local import at {import_path}")
349
+
350
+ # Copy aditional files like dataset infos file if needed
351
+ for file_name, original_path in additional_files:
352
+ destination_additional_path = os.path.join(importable_subdirectory, file_name)
353
+ if not os.path.exists(destination_additional_path) or not filecmp.cmp(
354
+ original_path, destination_additional_path
355
+ ):
356
+ shutil.copyfile(original_path, destination_additional_path)
357
+ return importable_local_file
358
+
359
+
360
+ def _create_importable_file(
361
+ local_path: str,
362
+ local_imports: List[Tuple[str, str]],
363
+ additional_files: List[Tuple[str, str]],
364
+ dynamic_modules_path: str,
365
+ module_namespace: str,
366
+ name: str,
367
+ download_mode: DownloadMode,
368
+ ) -> Tuple[str, str]:
369
+ importable_directory_path = os.path.join(dynamic_modules_path, module_namespace, name.replace("/", "--"))
370
+ Path(importable_directory_path).mkdir(parents=True, exist_ok=True)
371
+ (Path(importable_directory_path).parent / "__init__.py").touch(exist_ok=True)
372
+ hash = files_to_hash([local_path] + [loc[1] for loc in local_imports])
373
+ importable_local_file = _copy_script_and_other_resources_in_importable_dir(
374
+ name=name.split("/")[-1],
375
+ importable_directory_path=importable_directory_path,
376
+ subdirectory_name=hash,
377
+ original_local_path=local_path,
378
+ local_imports=local_imports,
379
+ additional_files=additional_files,
380
+ download_mode=download_mode,
381
+ )
382
+ logger.debug(f"Created importable dataset file at {importable_local_file}")
383
+ module_path = ".".join(
384
+ [os.path.basename(dynamic_modules_path), module_namespace, name.replace("/", "--"), hash, name.split("/")[-1]]
385
+ )
386
+ return module_path, hash
387
+
388
+
389
+ @dataclass
390
+ class ImportableModule:
391
+ module_path: str
392
+ hash: str
393
+
394
+
395
+ class _EvaluationModuleFactory:
396
+ def get_module(self) -> ImportableModule:
397
+ raise NotImplementedError
398
+
399
+
400
+ class LocalEvaluationModuleFactory(_EvaluationModuleFactory):
401
+ """Get the module of a local metric. The metric script is loaded from a local script."""
402
+
403
+ def __init__(
404
+ self,
405
+ path: str,
406
+ module_type: str = "metrics",
407
+ download_config: Optional[DownloadConfig] = None,
408
+ download_mode: Optional[DownloadMode] = None,
409
+ dynamic_modules_path: Optional[str] = None,
410
+ ):
411
+ self.path = path
412
+ self.module_type = module_type
413
+ self.name = Path(path).stem
414
+ self.download_config = download_config or DownloadConfig()
415
+ self.download_mode = download_mode
416
+ self.dynamic_modules_path = dynamic_modules_path
417
+
418
+ def get_module(self) -> ImportableModule:
419
+ # get script and other files
420
+ imports = get_imports(self.path)
421
+ local_imports = _download_additional_modules(
422
+ name=self.name,
423
+ base_path=str(Path(self.path).parent),
424
+ imports=imports,
425
+ download_config=self.download_config,
426
+ )
427
+ # copy the script and the files in an importable directory
428
+ dynamic_modules_path = self.dynamic_modules_path if self.dynamic_modules_path else init_dynamic_modules()
429
+ module_path, hash = _create_importable_file(
430
+ local_path=self.path,
431
+ local_imports=local_imports,
432
+ additional_files=[],
433
+ dynamic_modules_path=dynamic_modules_path,
434
+ module_namespace=self.module_type,
435
+ name=self.name,
436
+ download_mode=self.download_mode,
437
+ )
438
+ # make the new module to be noticed by the import system
439
+ importlib.invalidate_caches()
440
+ return ImportableModule(module_path, hash)
441
+
442
+
443
+ class HubEvaluationModuleFactory(_EvaluationModuleFactory):
444
+ """Get the module of a metric from a metric repository on the Hub."""
445
+
446
+ def __init__(
447
+ self,
448
+ name: str,
449
+ module_type: str = "metrics",
450
+ revision: Optional[Union[str, Version]] = None,
451
+ download_config: Optional[DownloadConfig] = None,
452
+ download_mode: Optional[DownloadMode] = None,
453
+ dynamic_modules_path: Optional[str] = None,
454
+ ):
455
+ self.name = name
456
+ self.module_type = module_type
457
+ self.revision = revision
458
+ self.download_config = download_config or DownloadConfig()
459
+ self.download_mode = download_mode
460
+ self.dynamic_modules_path = dynamic_modules_path
461
+ assert self.name.count("/") == 1
462
+ increase_load_count(name, resource_type="metric")
463
+
464
+ def download_loading_script(self, revision) -> str:
465
+ file_path = hf_hub_url(path=self.name, name=self.name.split("/")[1] + ".py", revision=revision)
466
+ download_config = self.download_config.copy()
467
+ if download_config.download_desc is None:
468
+ download_config.download_desc = "Downloading builder script"
469
+ return cached_path(file_path, download_config=download_config)
470
+
471
+ def get_module(self) -> ImportableModule:
472
+ revision = self.revision or os.getenv("HF_SCRIPTS_VERSION", SCRIPTS_VERSION)
473
+
474
+ if re.match(r"\d*\.\d*\.\d*", revision): # revision is version number (three digits separated by full stops)
475
+ revision = "v" + revision # tagging convention on evaluate repository starts with v
476
+
477
+ # get script and other files
478
+ try:
479
+ local_path = self.download_loading_script(revision)
480
+ except FileNotFoundError as err:
481
+ # if there is no file found with current revision tag try to load main
482
+ if self.revision is None and os.getenv("HF_SCRIPTS_VERSION", SCRIPTS_VERSION) != "main":
483
+ revision = "main"
484
+ local_path = self.download_loading_script(revision)
485
+ else:
486
+ raise err
487
+
488
+ imports = get_imports(local_path)
489
+ local_imports = _download_additional_modules(
490
+ name=self.name,
491
+ base_path=hf_hub_url(path=self.name, name="", revision=revision),
492
+ imports=imports,
493
+ download_config=self.download_config,
494
+ )
495
+ # copy the script and the files in an importable directory
496
+ dynamic_modules_path = self.dynamic_modules_path if self.dynamic_modules_path else init_dynamic_modules()
497
+ module_path, hash = _create_importable_file(
498
+ local_path=local_path,
499
+ local_imports=local_imports,
500
+ additional_files=[],
501
+ dynamic_modules_path=dynamic_modules_path,
502
+ module_namespace=self.module_type,
503
+ name=self.name,
504
+ download_mode=self.download_mode,
505
+ )
506
+ # make the new module to be noticed by the import system
507
+ importlib.invalidate_caches()
508
+ return ImportableModule(module_path, hash)
509
+
510
+
511
+ class CachedEvaluationModuleFactory(_EvaluationModuleFactory):
512
+ """
513
+ Get the module of a metric that has been loaded once already and cached.
514
+ The script that is loaded from the cache is the most recent one with a matching name.
515
+ """
516
+
517
+ def __init__(
518
+ self,
519
+ name: str,
520
+ module_type: str = "metrics",
521
+ dynamic_modules_path: Optional[str] = None,
522
+ ):
523
+ self.name = name
524
+ self.module_type = module_type
525
+ self.dynamic_modules_path = dynamic_modules_path
526
+ assert self.name.count("/") == 0
527
+
528
+ def get_module(self) -> ImportableModule:
529
+ dynamic_modules_path = self.dynamic_modules_path if self.dynamic_modules_path else init_dynamic_modules()
530
+ importable_directory_path = os.path.join(dynamic_modules_path, self.module_type, self.name)
531
+ hashes = (
532
+ [h for h in os.listdir(importable_directory_path) if len(h) == 64]
533
+ if os.path.isdir(importable_directory_path)
534
+ else None
535
+ )
536
+ if not hashes:
537
+ raise FileNotFoundError(f"Metric {self.name} is not cached in {dynamic_modules_path}")
538
+ # get most recent
539
+
540
+ def _get_modification_time(module_hash):
541
+ return (
542
+ (Path(importable_directory_path) / module_hash / (self.name.split("--")[-1] + ".py")).stat().st_mtime
543
+ )
544
+
545
+ hash = sorted(hashes, key=_get_modification_time)[-1]
546
+ logger.warning(
547
+ f"Using the latest cached version of the module from {os.path.join(importable_directory_path, hash)} "
548
+ f"(last modified on {time.ctime(_get_modification_time(hash))}) since it "
549
+ f"couldn't be found locally at {self.name}, or remotely on the Hugging Face Hub."
550
+ )
551
+ # make the new module to be noticed by the import system
552
+ module_path = ".".join(
553
+ [os.path.basename(dynamic_modules_path), self.module_type, self.name, hash, self.name.split("--")[-1]]
554
+ )
555
+ importlib.invalidate_caches()
556
+ return ImportableModule(module_path, hash)
557
+
558
+
559
+ def evaluation_module_factory(
560
+ path: str,
561
+ module_type: Optional[str] = None,
562
+ revision: Optional[Union[str, Version]] = None,
563
+ download_config: Optional[DownloadConfig] = None,
564
+ download_mode: Optional[DownloadMode] = None,
565
+ force_local_path: Optional[str] = None,
566
+ dynamic_modules_path: Optional[str] = None,
567
+ **download_kwargs,
568
+ ) -> ImportableModule:
569
+ """
570
+ Download/extract/cache a metric module.
571
+
572
+ Metrics codes are cached inside the the dynamic modules cache to allow easy import (avoid ugly sys.path tweaks).
573
+
574
+ Args:
575
+
576
+ path (str): Path or name of the metric script.
577
+
578
+ - if ``path`` is a local metric script or a directory containing a local metric script (if the script has the same name as the directory):
579
+ -> load the module from the metric script
580
+ e.g. ``'./metrics/accuracy'`` or ``'./metrics/accuracy/accuracy.py'``.
581
+ - if ``path`` is a metric on the Hugging Face Hub (ex: `glue`, `squad`)
582
+ -> load the module from the metric script in the github repository at huggingface/datasets
583
+ e.g. ``'accuracy'`` or ``'rouge'``.
584
+
585
+ revision (Optional ``Union[str, datasets.Version]``):
586
+ If specified, the module will be loaded from the datasets repository at this version.
587
+ By default:
588
+ - it is set to the local version of the lib.
589
+ - it will also try to load it from the master branch if it's not available at the local version of the lib.
590
+ Specifying a version that is different from your local version of the lib might cause compatibility issues.
591
+ download_config (:class:`DownloadConfig`, optional): Specific download configuration parameters.
592
+ download_mode (:class:`DownloadMode`, default ``REUSE_DATASET_IF_EXISTS``): Download/generate mode.
593
+ force_local_path (Optional str): Optional path to a local path to download and prepare the script to.
594
+ Used to inspect or modify the script folder.
595
+ dynamic_modules_path (Optional str, defaults to HF_MODULES_CACHE / "datasets_modules", i.e. ~/.cache/huggingface/modules/datasets_modules):
596
+ Optional path to the directory in which the dynamic modules are saved. It must have been initialized with :obj:`init_dynamic_modules`.
597
+ By default the datasets and metrics are stored inside the `datasets_modules` module.
598
+ download_kwargs: optional attributes for DownloadConfig() which will override the attributes in download_config if supplied.
599
+
600
+ Returns:
601
+ ImportableModule
602
+ """
603
+ if download_config is None:
604
+ download_config = DownloadConfig(**download_kwargs)
605
+ download_mode = DownloadMode(download_mode or DownloadMode.REUSE_DATASET_IF_EXISTS)
606
+ download_config.extract_compressed_file = True
607
+ download_config.force_extract = True
608
+
609
+ filename = list(filter(lambda x: x, path.replace(os.sep, "/").split("/")))[-1]
610
+ if not filename.endswith(".py"):
611
+ filename = filename + ".py"
612
+ combined_path = os.path.join(path, filename)
613
+ # Try locally
614
+ if path.endswith(filename):
615
+ if os.path.isfile(path):
616
+ return LocalEvaluationModuleFactory(
617
+ path, download_mode=download_mode, dynamic_modules_path=dynamic_modules_path
618
+ ).get_module()
619
+ else:
620
+ raise FileNotFoundError(f"Couldn't find a metric script at {relative_to_absolute_path(path)}")
621
+ elif os.path.isfile(combined_path):
622
+ return LocalEvaluationModuleFactory(
623
+ combined_path, download_mode=download_mode, dynamic_modules_path=dynamic_modules_path
624
+ ).get_module()
625
+ elif is_relative_path(path) and path.count("/") <= 1 and not force_local_path:
626
+ try:
627
+ # load a canonical evaluation module from hub
628
+ if path.count("/") == 0:
629
+ # if no type provided look through all possible modules
630
+ if module_type is None:
631
+ for current_type in ["metric", "comparison", "measurement"]:
632
+ try:
633
+ return HubEvaluationModuleFactory(
634
+ f"evaluate-{current_type}/{path}",
635
+ revision=revision,
636
+ download_config=download_config,
637
+ download_mode=download_mode,
638
+ dynamic_modules_path=dynamic_modules_path,
639
+ ).get_module()
640
+ except ConnectionError:
641
+ pass
642
+ raise FileNotFoundError
643
+ # if module_type provided load specific module_type
644
+ else:
645
+ return HubEvaluationModuleFactory(
646
+ f"evaluate-{module_type}/{path}",
647
+ revision=revision,
648
+ download_config=download_config,
649
+ download_mode=download_mode,
650
+ dynamic_modules_path=dynamic_modules_path,
651
+ ).get_module()
652
+ # load community evaluation module from hub
653
+ elif path.count("/") == 1:
654
+ return HubEvaluationModuleFactory(
655
+ path,
656
+ revision=revision,
657
+ download_config=download_config,
658
+ download_mode=download_mode,
659
+ dynamic_modules_path=dynamic_modules_path,
660
+ ).get_module()
661
+ except Exception as e1: # noqa: all the attempts failed, before raising the error we should check if the module is already cached.
662
+ # if it's a canonical module we need to check if it's any of the types
663
+ if path.count("/") == 0:
664
+ for current_type in ["metric", "comparison", "measurement"]:
665
+ try:
666
+ return CachedEvaluationModuleFactory(
667
+ f"evaluate-{current_type}--{path}", dynamic_modules_path=dynamic_modules_path
668
+ ).get_module()
669
+ except Exception as e2: # noqa: if it's not in the cache, then it doesn't exist.
670
+ pass
671
+ # if it's a community module we just need to check on path
672
+ elif path.count("/") == 1:
673
+ try:
674
+ return CachedEvaluationModuleFactory(
675
+ path.replace("/", "--"), dynamic_modules_path=dynamic_modules_path
676
+ ).get_module()
677
+ except Exception as e2: # noqa: if it's not in the cache, then it doesn't exist.
678
+ pass
679
+ if not isinstance(e1, (ConnectionError, FileNotFoundError)):
680
+ raise e1 from None
681
+ raise FileNotFoundError(
682
+ f"Couldn't find a module script at {relative_to_absolute_path(combined_path)}. "
683
+ f"Module '{path}' doesn't exist on the Hugging Face Hub either."
684
+ ) from None
685
+ else:
686
+ raise FileNotFoundError(f"Couldn't find a module script at {relative_to_absolute_path(combined_path)}.")
687
+
688
+
689
+ def load(
690
+ path: str,
691
+ config_name: Optional[str] = None,
692
+ module_type: Optional[str] = None,
693
+ process_id: int = 0,
694
+ num_process: int = 1,
695
+ cache_dir: Optional[str] = None,
696
+ experiment_id: Optional[str] = None,
697
+ keep_in_memory: bool = False,
698
+ download_config: Optional[DownloadConfig] = None,
699
+ download_mode: Optional[DownloadMode] = None,
700
+ revision: Optional[Union[str, Version]] = None,
701
+ **init_kwargs,
702
+ ) -> EvaluationModule:
703
+ """Load a [`~evaluate.EvaluationModule`].
704
+
705
+ Args:
706
+
707
+ path (`str`):
708
+ Path to the evaluation processing script with the evaluation builder. Can be either:
709
+ - a local path to processing script or the directory containing the script (if the script has the same name as the directory),
710
+ e.g. `'./metrics/rouge'` or `'./metrics/rouge/rouge.py'`
711
+ - a evaluation module identifier on the HuggingFace evaluate repo e.g. `'rouge'` or `'bleu'` that are in either `'metrics/'`,
712
+ `'comparisons/'`, or `'measurements/'` depending on the provided `module_type`
713
+ config_name (`str`, *optional*):
714
+ Selecting a configuration for the metric (e.g. the GLUE metric has a configuration for each subset).
715
+ module_type (`str`, default `'metric'`):
716
+ Type of evaluation module, can be one of `'metric'`, `'comparison'`, or `'measurement'`.
717
+ process_id (`int`, *optional*):
718
+ For distributed evaluation: id of the process.
719
+ num_process (`int`, *optional*):
720
+ For distributed evaluation: total number of processes.
721
+ cache_dir (`str`, *optional*):
722
+ Path to store the temporary predictions and references (default to `~/.cache/huggingface/evaluate/`).
723
+ experiment_id (`str`):
724
+ A specific experiment id. This is used if several distributed evaluations share the same file system.
725
+ This is useful to compute metrics in distributed setups (in particular non-additive metrics like F1).
726
+ keep_in_memory (`bool`):
727
+ Whether to store the temporary results in memory (defaults to `False`).
728
+ download_config ([`~evaluate.DownloadConfig`], *optional*):
729
+ Specific download configuration parameters.
730
+ download_mode ([`DownloadMode`], defaults to `REUSE_DATASET_IF_EXISTS`):
731
+ Download/generate mode.
732
+ revision (`Union[str, evaluate.Version]`, *optional*):
733
+ If specified, the module will be loaded from the datasets repository
734
+ at this version. By default it is set to the local version of the lib. Specifying a version that is different from
735
+ your local version of the lib might cause compatibility issues.
736
+
737
+ Returns:
738
+ [`evaluate.EvaluationModule`]
739
+
740
+ Example:
741
+
742
+ ```py
743
+ >>> from evaluate import load
744
+ >>> accuracy = load("accuracy")
745
+ ```
746
+ """
747
+ download_mode = DownloadMode(download_mode or DownloadMode.REUSE_DATASET_IF_EXISTS)
748
+ evaluation_module = evaluation_module_factory(
749
+ path, module_type=module_type, revision=revision, download_config=download_config, download_mode=download_mode
750
+ )
751
+ evaluation_cls = import_main_class(evaluation_module.module_path)
752
+ evaluation_instance = evaluation_cls(
753
+ config_name=config_name,
754
+ process_id=process_id,
755
+ num_process=num_process,
756
+ cache_dir=cache_dir,
757
+ keep_in_memory=keep_in_memory,
758
+ experiment_id=experiment_id,
759
+ hash=evaluation_module.hash,
760
+ **init_kwargs,
761
+ )
762
+
763
+ if module_type and module_type != evaluation_instance.module_type:
764
+ raise TypeError(
765
+ f"No module of module type '{module_type}' not found for '{path}' locally, or on the Hugging Face Hub. Found module of module type '{evaluation_instance.module_type}' instead."
766
+ )
767
+
768
+ # Download and prepare resources for the metric
769
+ evaluation_instance.download_and_prepare(download_config=download_config)
770
+
771
+ return evaluation_instance
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/module.py ADDED
@@ -0,0 +1,1034 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 The HuggingFace 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
+ # Lint as: python3
16
+ """ EvaluationModule base class."""
17
+ import collections
18
+ import itertools
19
+ import os
20
+ import types
21
+ import uuid
22
+ from typing import Any, Dict, List, Optional, Tuple, Union
23
+
24
+ import numpy as np
25
+ import pyarrow as pa
26
+ from datasets import DatasetInfo, DownloadConfig, DownloadManager
27
+ from datasets.arrow_dataset import Dataset
28
+ from datasets.arrow_reader import ArrowReader
29
+ from datasets.arrow_writer import ArrowWriter
30
+ from datasets.features import Features, Sequence, Value
31
+ from datasets.features.features import _check_non_null_non_empty_recursive
32
+ from datasets.utils.filelock import BaseFileLock, FileLock, Timeout
33
+ from datasets.utils.py_utils import copyfunc, temp_seed, zip_dict
34
+
35
+ from . import config
36
+ from .info import EvaluationModuleInfo
37
+ from .naming import camelcase_to_snakecase
38
+ from .utils.logging import get_logger
39
+
40
+
41
+ logger = get_logger(__name__)
42
+
43
+
44
+ class FileFreeLock(BaseFileLock):
45
+ """Thread lock until a file **cannot** be locked"""
46
+
47
+ def __init__(self, lock_file, *args, **kwargs):
48
+ self.filelock = FileLock(lock_file)
49
+ super().__init__(lock_file, *args, **kwargs)
50
+ self._lock_file_fd = None
51
+
52
+ def _acquire(self):
53
+ try:
54
+ self.filelock.acquire(timeout=0.01, poll_interval=0.02) # Try to lock once
55
+ except Timeout:
56
+ # We couldn't acquire the lock, the file is locked!
57
+ self._lock_file_fd = self.filelock.lock_file
58
+ else:
59
+ # We were able to acquire the lock, the file is not yet locked!
60
+ self.filelock.release()
61
+ self._lock_file_fd = None
62
+
63
+ def _release(self):
64
+ self._lock_file_fd = None
65
+
66
+ @property
67
+ def is_locked(self) -> bool:
68
+ return self._lock_file_fd is not None
69
+
70
+
71
+ # lists - summarize long lists similarly to NumPy
72
+ # arrays/tensors - let the frameworks control formatting
73
+ def summarize_if_long_list(obj):
74
+ if type(obj) is not list or len(obj) <= 6:
75
+ return f"{obj}"
76
+
77
+ def format_chunk(chunk):
78
+ return ", ".join(repr(x) for x in chunk)
79
+
80
+ return f"[{format_chunk(obj[:3])}, ..., {format_chunk(obj[-3:])}]"
81
+
82
+
83
+ class EvaluationModuleInfoMixin:
84
+ """This base class exposes some attributes of EvaluationModuleInfo
85
+ at the base level of the EvaluationModule for easy access.
86
+ """
87
+
88
+ def __init__(self, info: EvaluationModuleInfo):
89
+ self._module_info = info
90
+
91
+ @property
92
+ def info(self):
93
+ """:class:`evaluate.EvaluationModuleInfo` object containing all the metadata in the evaluation module."""
94
+ return self._module_info
95
+
96
+ @property
97
+ def name(self) -> str:
98
+ return self._module_info.module_name
99
+
100
+ @property
101
+ def experiment_id(self) -> Optional[str]:
102
+ return self._module_info.experiment_id
103
+
104
+ @property
105
+ def description(self) -> str:
106
+ return self._module_info.description
107
+
108
+ @property
109
+ def citation(self) -> str:
110
+ return self._module_info.citation
111
+
112
+ @property
113
+ def features(self) -> Features:
114
+ return self._module_info.features
115
+
116
+ @property
117
+ def inputs_description(self) -> str:
118
+ return self._module_info.inputs_description
119
+
120
+ @property
121
+ def homepage(self) -> Optional[str]:
122
+ return self._module_info.homepage
123
+
124
+ @property
125
+ def license(self) -> str:
126
+ return self._module_info.license
127
+
128
+ @property
129
+ def codebase_urls(self) -> Optional[List[str]]:
130
+ return self._module_info.codebase_urls
131
+
132
+ @property
133
+ def reference_urls(self) -> Optional[List[str]]:
134
+ return self._module_info.reference_urls
135
+
136
+ @property
137
+ def streamable(self) -> bool:
138
+ return self._module_info.streamable
139
+
140
+ @property
141
+ def format(self) -> Optional[str]:
142
+ return self._module_info.format
143
+
144
+ @property
145
+ def module_type(self) -> str:
146
+ return self._module_info.module_type
147
+
148
+
149
+ class EvaluationModule(EvaluationModuleInfoMixin):
150
+ """A `EvaluationModule` is the base class and common API for metrics, comparisons, and measurements.
151
+
152
+ Args:
153
+ config_name (`str`):
154
+ This is used to define a hash specific to a module computation script and prevents the module's data
155
+ to be overridden when the module loading script is modified.
156
+ keep_in_memory (`bool`):
157
+ Keep all predictions and references in memory. Not possible in distributed settings.
158
+ cache_dir (`str`):
159
+ Path to a directory in which temporary prediction/references data will be stored.
160
+ The data directory should be located on a shared file-system in distributed setups.
161
+ num_process (`int`):
162
+ Specify the total number of nodes in a distributed settings.
163
+ This is useful to compute module in distributed setups (in particular non-additive modules like F1).
164
+ process_id (`int`):
165
+ Specify the id of the current process in a distributed setup (between 0 and num_process-1)
166
+ This is useful to compute module in distributed setups (in particular non-additive metrics like F1).
167
+ seed (`int`, optional):
168
+ If specified, this will temporarily set numpy's random seed when [`~evaluate.EvaluationModule.compute`] is run.
169
+ experiment_id (`str`):
170
+ A specific experiment id. This is used if several distributed evaluations share the same file system.
171
+ This is useful to compute module in distributed setups (in particular non-additive metrics like F1).
172
+ hash (`str`):
173
+ Used to identify the evaluation module according to the hashed file contents.
174
+ max_concurrent_cache_files (`int`):
175
+ Max number of concurrent module cache files (default `10000`).
176
+ timeout (`Union[int, float]`):
177
+ Timeout in second for distributed setting synchronization.
178
+ """
179
+
180
+ def __init__(
181
+ self,
182
+ config_name: Optional[str] = None,
183
+ keep_in_memory: bool = False,
184
+ cache_dir: Optional[str] = None,
185
+ num_process: int = 1,
186
+ process_id: int = 0,
187
+ seed: Optional[int] = None,
188
+ experiment_id: Optional[str] = None,
189
+ hash: str = None,
190
+ max_concurrent_cache_files: int = 10000,
191
+ timeout: Union[int, float] = 100,
192
+ **kwargs,
193
+ ):
194
+ # prepare info
195
+ self.config_name = config_name or "default"
196
+ info = self._info()
197
+ info.module_name = camelcase_to_snakecase(self.__class__.__name__)
198
+ info.config_name = self.config_name
199
+ info.experiment_id = experiment_id or "default_experiment"
200
+ EvaluationModuleInfoMixin.__init__(self, info) # For easy access on low level
201
+
202
+ # Safety checks on num_process and process_id
203
+ if not isinstance(process_id, int) or process_id < 0:
204
+ raise ValueError("'process_id' should be a number greater than 0")
205
+ if not isinstance(num_process, int) or num_process <= process_id:
206
+ raise ValueError("'num_process' should be a number greater than process_id")
207
+ if keep_in_memory and num_process != 1:
208
+ raise ValueError("Using 'keep_in_memory' is not possible in distributed setting (num_process > 1).")
209
+
210
+ self.num_process = num_process
211
+ self.process_id = process_id
212
+ self.max_concurrent_cache_files = max_concurrent_cache_files
213
+
214
+ self.keep_in_memory = keep_in_memory
215
+ self._data_dir_root = os.path.expanduser(cache_dir or config.HF_METRICS_CACHE)
216
+ self.data_dir = self._build_data_dir()
217
+ if seed is None:
218
+ _, seed, pos, *_ = np.random.get_state()
219
+ self.seed: int = seed[pos] if pos < 624 else seed[0]
220
+ else:
221
+ self.seed: int = seed
222
+ self.timeout: Union[int, float] = timeout
223
+
224
+ # Update 'compute' and 'add' docstring
225
+ # methods need to be copied otherwise it changes the docstrings of every instance
226
+ self.compute = types.MethodType(copyfunc(self.compute), self)
227
+ self.add_batch = types.MethodType(copyfunc(self.add_batch), self)
228
+ self.add = types.MethodType(copyfunc(self.add), self)
229
+ self.compute.__func__.__doc__ += self.info.inputs_description
230
+ self.add_batch.__func__.__doc__ += self.info.inputs_description
231
+ self.add.__func__.__doc__ += self.info.inputs_description
232
+
233
+ # self.arrow_schema = pa.schema(field for field in self.info.features.type)
234
+ self.selected_feature_format = None
235
+ self.buf_writer = None
236
+ self.writer = None
237
+ self.writer_batch_size = None
238
+ self.data = None
239
+
240
+ # This is the cache file we store our predictions/references in
241
+ # Keep it None for now so we can (cloud)pickle the object
242
+ self.cache_file_name = None
243
+ self.filelock = None
244
+ self.rendez_vous_lock = None
245
+
246
+ # This is all the cache files on which we have a lock when we are in a distributed setting
247
+ self.file_paths = None
248
+ self.filelocks = None
249
+
250
+ # This fingerprints the evaluation module according to the hashed contents of the module code
251
+ self._hash = hash
252
+
253
+ def __len__(self):
254
+ """Return the number of examples (predictions or predictions/references pair)
255
+ currently stored in the evaluation module's cache.
256
+ """
257
+ return 0 if self.writer is None else len(self.writer)
258
+
259
+ def __repr__(self):
260
+ return (
261
+ f'EvaluationModule(name: "{self.name}", module_type: "{self.module_type}", '
262
+ f'features: {self.features}, usage: """{self.inputs_description}""", '
263
+ f"stored examples: {len(self)})"
264
+ )
265
+
266
+ def _build_data_dir(self):
267
+ """Path of this evaluation module in cache_dir:
268
+ Will be:
269
+ self._data_dir_root/self.name/self.config_name/self.hash (if not none)/
270
+ If any of these element is missing or if ``with_version=False`` the corresponding subfolders are dropped.
271
+ """
272
+ builder_data_dir = self._data_dir_root
273
+ builder_data_dir = os.path.join(builder_data_dir, self.name, self.config_name)
274
+ os.makedirs(builder_data_dir, exist_ok=True)
275
+ return builder_data_dir
276
+
277
+ def _create_cache_file(self, timeout=1) -> Tuple[str, FileLock]:
278
+ """Create a new cache file. If the default cache file is used, we generated a new hash."""
279
+ file_path = os.path.join(self.data_dir, f"{self.experiment_id}-{self.num_process}-{self.process_id}.arrow")
280
+ filelock = None
281
+ for i in range(self.max_concurrent_cache_files):
282
+ filelock = FileLock(file_path + ".lock")
283
+ try:
284
+ filelock.acquire(timeout=timeout)
285
+ except Timeout:
286
+ # If we have reached the max number of attempts or we are not allow to find a free name (distributed setup)
287
+ # We raise an error
288
+ if self.num_process != 1:
289
+ raise ValueError(
290
+ f"Error in _create_cache_file: another evaluation module instance is already using the local cache file at {file_path}. "
291
+ f"Please specify an experiment_id (currently: {self.experiment_id}) to avoid collision "
292
+ f"between distributed evaluation module instances."
293
+ ) from None
294
+ if i == self.max_concurrent_cache_files - 1:
295
+ raise ValueError(
296
+ f"Cannot acquire lock, too many evaluation module instance are operating concurrently on this file system."
297
+ f"You should set a larger value of max_concurrent_cache_files when creating the evaluation module "
298
+ f"(current value is {self.max_concurrent_cache_files})."
299
+ ) from None
300
+ # In other cases (allow to find new file name + not yet at max num of attempts) we can try to sample a new hashing name.
301
+ file_uuid = str(uuid.uuid4())
302
+ file_path = os.path.join(
303
+ self.data_dir, f"{self.experiment_id}-{file_uuid}-{self.num_process}-{self.process_id}.arrow"
304
+ )
305
+ else:
306
+ break
307
+
308
+ return file_path, filelock
309
+
310
+ def _get_all_cache_files(self) -> Tuple[List[str], List[FileLock]]:
311
+ """Get a lock on all the cache files in a distributed setup.
312
+ We wait for timeout second to let all the distributed node finish their tasks (default is 100 seconds).
313
+ """
314
+ if self.num_process == 1:
315
+ if self.cache_file_name is None:
316
+ raise ValueError(
317
+ "Evaluation module cache file doesn't exist. Please make sure that you call `add` or `add_batch` "
318
+ "at least once before calling `compute`."
319
+ )
320
+ file_paths = [self.cache_file_name]
321
+ else:
322
+ file_paths = [
323
+ os.path.join(self.data_dir, f"{self.experiment_id}-{self.num_process}-{process_id}.arrow")
324
+ for process_id in range(self.num_process)
325
+ ]
326
+
327
+ # Let's acquire a lock on each process files to be sure they are finished writing
328
+ filelocks = []
329
+ for process_id, file_path in enumerate(file_paths):
330
+ if process_id == 0: # process 0 already has its lock file
331
+ filelocks.append(self.filelock)
332
+ else:
333
+ filelock = FileLock(file_path + ".lock")
334
+ try:
335
+ filelock.acquire(timeout=self.timeout)
336
+ except Timeout:
337
+ raise ValueError(
338
+ f"Cannot acquire lock on cached file {file_path} for process {process_id}."
339
+ ) from None
340
+ else:
341
+ filelocks.append(filelock)
342
+
343
+ return file_paths, filelocks
344
+
345
+ def _check_all_processes_locks(self):
346
+ expected_lock_file_names = [
347
+ os.path.join(self.data_dir, f"{self.experiment_id}-{self.num_process}-{process_id}.arrow.lock")
348
+ for process_id in range(self.num_process)
349
+ ]
350
+ for expected_lock_file_name in expected_lock_file_names:
351
+ nofilelock = FileFreeLock(expected_lock_file_name)
352
+ try:
353
+ nofilelock.acquire(timeout=self.timeout)
354
+ except Timeout:
355
+ raise ValueError(
356
+ f"Expected to find locked file {expected_lock_file_name} from process {self.process_id} but it doesn't exist."
357
+ ) from None
358
+ else:
359
+ nofilelock.release()
360
+
361
+ def _check_rendez_vous(self):
362
+ expected_lock_file_name = os.path.join(self.data_dir, f"{self.experiment_id}-{self.num_process}-0.arrow.lock")
363
+ nofilelock = FileFreeLock(expected_lock_file_name)
364
+ try:
365
+ nofilelock.acquire(timeout=self.timeout)
366
+ except Timeout:
367
+ raise ValueError(
368
+ f"Expected to find locked file {expected_lock_file_name} from process {self.process_id} but it doesn't exist."
369
+ ) from None
370
+ else:
371
+ nofilelock.release()
372
+ lock_file_name = os.path.join(self.data_dir, f"{self.experiment_id}-{self.num_process}-rdv.lock")
373
+ rendez_vous_lock = FileLock(lock_file_name)
374
+ try:
375
+ rendez_vous_lock.acquire(timeout=self.timeout)
376
+ except Timeout:
377
+ raise ValueError(f"Couldn't acquire lock on {lock_file_name} from process {self.process_id}.") from None
378
+ else:
379
+ rendez_vous_lock.release()
380
+
381
+ def _finalize(self):
382
+ """Close all the writing process and load/gather the data
383
+ from all the nodes if main node or all_process is True.
384
+ """
385
+ if self.writer is not None:
386
+ self.writer.finalize()
387
+ self.writer = None
388
+ # release the locks of the processes > 0 so that process 0 can lock them to read + delete the data
389
+ if self.filelock is not None and self.process_id > 0:
390
+ self.filelock.release()
391
+
392
+ if self.keep_in_memory:
393
+ # Read the predictions and references
394
+ reader = ArrowReader(path=self.data_dir, info=DatasetInfo(features=self.selected_feature_format))
395
+ self.data = Dataset.from_buffer(self.buf_writer.getvalue())
396
+
397
+ elif self.process_id == 0:
398
+ # Let's acquire a lock on each node files to be sure they are finished writing
399
+ file_paths, filelocks = self._get_all_cache_files()
400
+
401
+ # Read the predictions and references
402
+ try:
403
+ reader = ArrowReader(path="", info=DatasetInfo(features=self.selected_feature_format))
404
+ self.data = Dataset(**reader.read_files([{"filename": f} for f in file_paths]))
405
+ except FileNotFoundError:
406
+ raise ValueError(
407
+ "Error in finalize: another evaluation module instance is already using the local cache file. "
408
+ "Please specify an experiment_id to avoid collision between distributed evaluation module instances."
409
+ ) from None
410
+
411
+ # Store file paths and locks and we will release/delete them after the computation.
412
+ self.file_paths = file_paths
413
+ self.filelocks = filelocks
414
+
415
+ def compute(self, *, predictions=None, references=None, **kwargs) -> Optional[dict]:
416
+ """Compute the evaluation module.
417
+
418
+ Usage of positional arguments is not allowed to prevent mistakes.
419
+
420
+ Args:
421
+ predictions (`list/array/tensor`, *optional*):
422
+ Predictions.
423
+ references (`list/array/tensor`, *optional*):
424
+ References.
425
+ **kwargs (optional):
426
+ Keyword arguments that will be forwarded to the evaluation module [`~evaluate.EvaluationModule.compute`]
427
+ method (see details in the docstring).
428
+
429
+ Return:
430
+ `dict` or `None`
431
+
432
+ - Dictionary with the results if this evaluation module is run on the main process (`process_id == 0`).
433
+ - `None` if the evaluation module is not run on the main process (`process_id != 0`).
434
+
435
+ ```py
436
+ >>> import evaluate
437
+ >>> accuracy = evaluate.load("accuracy")
438
+ >>> accuracy.compute(predictions=[0, 1, 1, 0], references=[0, 1, 0, 1])
439
+ ```
440
+ """
441
+ all_kwargs = {"predictions": predictions, "references": references, **kwargs}
442
+ if predictions is None and references is None:
443
+ missing_kwargs = {k: None for k in self._feature_names() if k not in all_kwargs}
444
+ all_kwargs.update(missing_kwargs)
445
+ else:
446
+ missing_inputs = [k for k in self._feature_names() if k not in all_kwargs]
447
+ if missing_inputs:
448
+ raise ValueError(
449
+ f"Evaluation module inputs are missing: {missing_inputs}. All required inputs are {list(self._feature_names())}"
450
+ )
451
+ inputs = {input_name: all_kwargs[input_name] for input_name in self._feature_names()}
452
+ compute_kwargs = {k: kwargs[k] for k in kwargs if k not in self._feature_names()}
453
+
454
+ if any(v is not None for v in inputs.values()):
455
+ self.add_batch(**inputs)
456
+ self._finalize()
457
+
458
+ self.cache_file_name = None
459
+ self.filelock = None
460
+ self.selected_feature_format = None
461
+
462
+ if self.process_id == 0:
463
+ self.data.set_format(type=self.info.format)
464
+
465
+ inputs = {input_name: self.data[input_name][:] for input_name in self._feature_names()}
466
+ with temp_seed(self.seed):
467
+ output = self._compute(**inputs, **compute_kwargs)
468
+
469
+ if self.buf_writer is not None:
470
+ self.buf_writer = None
471
+ del self.data
472
+ self.data = None
473
+ else:
474
+ # Release locks and delete all the cache files. Process 0 is released last.
475
+ for filelock, file_path in reversed(list(zip(self.filelocks, self.file_paths))):
476
+ logger.info(f"Removing {file_path}")
477
+ del self.data
478
+ self.data = None
479
+ del self.writer
480
+ self.writer = None
481
+ os.remove(file_path)
482
+ filelock.release()
483
+
484
+ return output
485
+ else:
486
+ return None
487
+
488
+ def add_batch(self, *, predictions=None, references=None, **kwargs):
489
+ """Add a batch of predictions and references for the evaluation module's stack.
490
+
491
+ Args:
492
+ predictions (`list/array/tensor`, *optional*):
493
+ Predictions.
494
+ references (`list/array/tensor`, *optional*):
495
+ References.
496
+
497
+ Example:
498
+
499
+ ```py
500
+ >>> import evaluate
501
+ >>> accuracy = evaluate.load("accuracy")
502
+ >>> for refs, preds in zip([[0,1],[0,1]], [[1,0],[0,1]]):
503
+ ... accuracy.add_batch(references=refs, predictions=preds)
504
+ ```
505
+ """
506
+ bad_inputs = [input_name for input_name in kwargs if input_name not in self._feature_names()]
507
+ if bad_inputs:
508
+ raise ValueError(
509
+ f"Bad inputs for evaluation module: {bad_inputs}. All required inputs are {list(self._feature_names())}"
510
+ )
511
+ batch = {"predictions": predictions, "references": references, **kwargs}
512
+ batch = {input_name: batch[input_name] for input_name in self._feature_names()}
513
+ if self.writer is None:
514
+ self.selected_feature_format = self._infer_feature_from_batch(batch)
515
+ self._init_writer()
516
+ try:
517
+ for key, column in batch.items():
518
+ if len(column) > 0:
519
+ self._enforce_nested_string_type(self.selected_feature_format[key], column[0])
520
+ batch = self.selected_feature_format.encode_batch(batch)
521
+ self.writer.write_batch(batch)
522
+ except (pa.ArrowInvalid, TypeError):
523
+ if any(len(batch[c]) != len(next(iter(batch.values()))) for c in batch):
524
+ col0 = next(iter(batch))
525
+ bad_col = [c for c in batch if len(batch[c]) != len(batch[col0])][0]
526
+ error_msg = (
527
+ f"Mismatch in the number of {col0} ({len(batch[col0])}) and {bad_col} ({len(batch[bad_col])})"
528
+ )
529
+ elif set(self.selected_feature_format) != {"references", "predictions"}:
530
+ error_msg = (
531
+ f"Module inputs don't match the expected format.\n"
532
+ f"Expected format: {self.selected_feature_format },\n"
533
+ )
534
+ error_msg_inputs = ",\n".join(
535
+ f"Input {input_name}: {summarize_if_long_list(batch[input_name])}"
536
+ for input_name in self.selected_feature_format
537
+ )
538
+ error_msg += error_msg_inputs
539
+ else:
540
+ error_msg = (
541
+ f"Predictions and/or references don't match the expected format.\n"
542
+ f"Expected format: {self.selected_feature_format },\n"
543
+ f"Input predictions: {summarize_if_long_list(predictions)},\n"
544
+ f"Input references: {summarize_if_long_list(references)}"
545
+ )
546
+ raise ValueError(error_msg) from None
547
+
548
+ def add(self, *, prediction=None, reference=None, **kwargs):
549
+ """Add one prediction and reference for the evaluation module's stack.
550
+
551
+ Args:
552
+ prediction (`list/array/tensor`, *optional*):
553
+ Predictions.
554
+ reference (`list/array/tensor`, *optional*):
555
+ References.
556
+
557
+ Example:
558
+
559
+ ```py
560
+ >>> import evaluate
561
+ >>> accuracy = evaluate.load("accuracy")
562
+ >>> accuracy.add(references=[0,1], predictions=[1,0])
563
+ ```
564
+ """
565
+ bad_inputs = [input_name for input_name in kwargs if input_name not in self._feature_names()]
566
+ if bad_inputs:
567
+ raise ValueError(
568
+ f"Bad inputs for evaluation module: {bad_inputs}. All required inputs are {list(self._feature_names())}"
569
+ )
570
+ example = {"predictions": prediction, "references": reference, **kwargs}
571
+ example = {input_name: example[input_name] for input_name in self._feature_names()}
572
+ if self.writer is None:
573
+ self.selected_feature_format = self._infer_feature_from_example(example)
574
+ self._init_writer()
575
+ try:
576
+ self._enforce_nested_string_type(self.selected_feature_format, example)
577
+ example = self.selected_feature_format.encode_example(example)
578
+ self.writer.write(example)
579
+ except (pa.ArrowInvalid, TypeError):
580
+ error_msg = (
581
+ f"Evaluation module inputs don't match the expected format.\n"
582
+ f"Expected format: {self.selected_feature_format},\n"
583
+ )
584
+ error_msg_inputs = ",\n".join(
585
+ f"Input {input_name}: {summarize_if_long_list(example[input_name])}"
586
+ for input_name in self.selected_feature_format
587
+ )
588
+ error_msg += error_msg_inputs
589
+ raise ValueError(error_msg) from None
590
+
591
+ def _infer_feature_from_batch(self, batch):
592
+ if isinstance(self.features, Features):
593
+ return self.features
594
+ else:
595
+ example = dict([(k, v[0]) for k, v in batch.items()])
596
+ return self._infer_feature_from_example(example)
597
+
598
+ def _infer_feature_from_example(self, example):
599
+ if isinstance(self.features, Features):
600
+ return self.features
601
+ else:
602
+ for features in self.features:
603
+ try:
604
+ self._enforce_nested_string_type(features, example)
605
+ features.encode_example(example)
606
+ return features
607
+ except (ValueError, TypeError):
608
+ continue
609
+ feature_strings = "\n".join([f"Feature option {i}: {feature}" for i, feature in enumerate(self.features)])
610
+ error_msg = (
611
+ f"Predictions and/or references don't match the expected format.\n"
612
+ f"Expected format:\n{feature_strings},\n"
613
+ f"Input predictions: {summarize_if_long_list(example['predictions'])},\n"
614
+ f"Input references: {summarize_if_long_list(example['references'])}"
615
+ )
616
+ raise ValueError(error_msg) from None
617
+
618
+ def _feature_names(self):
619
+ if isinstance(self.features, list):
620
+ feature_names = list(self.features[0].keys())
621
+ else:
622
+ feature_names = list(self.features.keys())
623
+ return feature_names
624
+
625
+ def _init_writer(self, timeout=1):
626
+ if self.num_process > 1:
627
+ if self.process_id == 0:
628
+ file_path = os.path.join(self.data_dir, f"{self.experiment_id}-{self.num_process}-rdv.lock")
629
+ self.rendez_vous_lock = FileLock(file_path)
630
+ try:
631
+ self.rendez_vous_lock.acquire(timeout=timeout)
632
+ except TimeoutError:
633
+ raise ValueError(
634
+ f"Error in _init_writer: another evalution module instance is already using the local cache file at {file_path}. "
635
+ f"Please specify an experiment_id (currently: {self.experiment_id}) to avoid collision "
636
+ f"between distributed evaluation module instances."
637
+ ) from None
638
+
639
+ if self.keep_in_memory:
640
+ self.buf_writer = pa.BufferOutputStream()
641
+ self.writer = ArrowWriter(
642
+ features=self.selected_feature_format, stream=self.buf_writer, writer_batch_size=self.writer_batch_size
643
+ )
644
+ else:
645
+ self.buf_writer = None
646
+
647
+ # Get cache file name and lock it
648
+ if self.cache_file_name is None or self.filelock is None:
649
+ cache_file_name, filelock = self._create_cache_file() # get ready
650
+ self.cache_file_name = cache_file_name
651
+ self.filelock = filelock
652
+
653
+ self.writer = ArrowWriter(
654
+ features=self.selected_feature_format,
655
+ path=self.cache_file_name,
656
+ writer_batch_size=self.writer_batch_size,
657
+ )
658
+ # Setup rendez-vous here if
659
+ if self.num_process > 1:
660
+ if self.process_id == 0:
661
+ self._check_all_processes_locks() # wait for everyone to be ready
662
+ self.rendez_vous_lock.release() # let everyone go
663
+ else:
664
+ self._check_rendez_vous() # wait for master to be ready and to let everyone go
665
+
666
+ def _info(self) -> EvaluationModuleInfo:
667
+ """Construct the EvaluationModuleInfo object. See `EvaluationModuleInfo` for details.
668
+
669
+ Warning: This function is only called once and the result is cached for all
670
+ following .info() calls.
671
+
672
+ Returns:
673
+ info: (EvaluationModuleInfo) The EvaluationModule information
674
+ """
675
+ raise NotImplementedError
676
+
677
+ def download_and_prepare(
678
+ self,
679
+ download_config: Optional[DownloadConfig] = None,
680
+ dl_manager: Optional[DownloadManager] = None,
681
+ ):
682
+ """Downloads and prepares evaluation module for reading.
683
+
684
+ Args:
685
+ download_config ([`DownloadConfig`], *optional*):
686
+ Specific download configuration parameters.
687
+ dl_manager ([`DownloadManager`], *optional*):
688
+ Specific download manager to use.
689
+
690
+ Example:
691
+
692
+ ```py
693
+ >>> import evaluate
694
+ ```
695
+ """
696
+ if dl_manager is None:
697
+ if download_config is None:
698
+ download_config = DownloadConfig()
699
+ download_config.cache_dir = os.path.join(self.data_dir, "downloads")
700
+ download_config.force_download = False
701
+
702
+ dl_manager = DownloadManager(
703
+ dataset_name=self.name, download_config=download_config, data_dir=self.data_dir
704
+ )
705
+
706
+ self._download_and_prepare(dl_manager)
707
+
708
+ def _download_and_prepare(self, dl_manager):
709
+ """Downloads and prepares resources for the evaluation module.
710
+
711
+ This is the internal implementation to overwrite called when user calls
712
+ `download_and_prepare`. It should download all required resources for the evaluation module.
713
+
714
+ Args:
715
+ dl_manager (:class:`DownloadManager`): `DownloadManager` used to download and cache data.
716
+ """
717
+ return None
718
+
719
+ def _compute(self, *, predictions=None, references=None, **kwargs) -> Dict[str, Any]:
720
+ """This method defines the common API for all the evaluation module in the library"""
721
+ raise NotImplementedError
722
+
723
+ def __del__(self):
724
+ if hasattr(self, "filelock") and self.filelock is not None:
725
+ self.filelock.release()
726
+ if hasattr(self, "rendez_vous_lock") and self.rendez_vous_lock is not None:
727
+ self.rendez_vous_lock.release()
728
+ if hasattr(self, "writer"): # in case it was already deleted
729
+ del self.writer
730
+ if hasattr(self, "data"): # in case it was already deleted
731
+ del self.data
732
+
733
+ def _enforce_nested_string_type(self, schema, obj):
734
+ """
735
+ Recursively checks if there is any Value feature of type string and throws TypeError if corresponding object is not a string.
736
+ Since any Python object can be cast to string this avoids implicitly casting wrong input types (e.g. lists) to string without error.
737
+ """
738
+ # Nested structures: we allow dict, list, tuples, sequences
739
+ if isinstance(schema, dict):
740
+ return [self._enforce_nested_string_type(sub_schema, o) for k, (sub_schema, o) in zip_dict(schema, obj)]
741
+
742
+ elif isinstance(schema, (list, tuple)):
743
+ sub_schema = schema[0]
744
+ return [self._enforce_nested_string_type(sub_schema, o) for o in obj]
745
+ elif isinstance(schema, Sequence):
746
+ # We allow to reverse list of dict => dict of list for compatiblity with tfds
747
+ if isinstance(schema.feature, dict):
748
+ if isinstance(obj, (list, tuple)):
749
+ # obj is a list of dict
750
+ for k, dict_tuples in zip_dict(schema.feature, *obj):
751
+ for sub_obj in dict_tuples[1:]:
752
+ if _check_non_null_non_empty_recursive(sub_obj, dict_tuples[0]):
753
+ self._enforce_nested_string_type(dict_tuples[0], sub_obj)
754
+ break
755
+ return None
756
+ else:
757
+ # obj is a single dict
758
+ for k, (sub_schema, sub_objs) in zip_dict(schema.feature, obj):
759
+ for sub_obj in sub_objs:
760
+ if _check_non_null_non_empty_recursive(sub_obj, sub_schema):
761
+ self._enforce_nested_string_type(sub_schema, sub_obj)
762
+ break
763
+ return None
764
+ # schema.feature is not a dict
765
+ if isinstance(obj, str): # don't interpret a string as a list
766
+ raise ValueError(f"Got a string but expected a list instead: '{obj}'")
767
+ if obj is None:
768
+ return None
769
+ else:
770
+ if len(obj) > 0:
771
+ for first_elmt in obj:
772
+ if _check_non_null_non_empty_recursive(first_elmt, schema.feature):
773
+ break
774
+ if not isinstance(first_elmt, list):
775
+ return self._enforce_nested_string_type(schema.feature, first_elmt)
776
+
777
+ elif isinstance(schema, Value):
778
+ if pa.types.is_string(schema.pa_type) and not isinstance(obj, str):
779
+ raise TypeError(f"Expected type str but got {type(obj)}.")
780
+
781
+
782
+ class Metric(EvaluationModule):
783
+ """A Metric is the base class and common API for all metrics.
784
+
785
+ Args:
786
+ config_name (`str`):
787
+ This is used to define a hash specific to a metric computation script and prevents the metric's data
788
+ to be overridden when the metric loading script is modified.
789
+ keep_in_memory (`bool`):
790
+ Keep all predictions and references in memory. Not possible in distributed settings.
791
+ cache_dir (`str`):
792
+ Path to a directory in which temporary prediction/references data will be stored.
793
+ The data directory should be located on a shared file-system in distributed setups.
794
+ num_process (`int`):
795
+ Specify the total number of nodes in a distributed settings.
796
+ This is useful to compute metrics in distributed setups (in particular non-additive metrics like F1).
797
+ process_id (`int`):
798
+ Specify the id of the current process in a distributed setup (between 0 and num_process-1)
799
+ This is useful to compute metrics in distributed setups (in particular non-additive metrics like F1).
800
+ seed (`int`, *optional*):
801
+ If specified, this will temporarily set numpy's random seed when [`~evaluate.Metric.compute`] is run.
802
+ experiment_id (`str`):
803
+ A specific experiment id. This is used if several distributed evaluations share the same file system.
804
+ This is useful to compute metrics in distributed setups (in particular non-additive metrics like F1).
805
+ max_concurrent_cache_files (`int`):
806
+ Max number of concurrent metric cache files (default `10000`).
807
+ timeout (`Union[int, float]`):
808
+ Timeout in second for distributed setting synchronization.
809
+ """
810
+
811
+
812
+ class Comparison(EvaluationModule):
813
+ """A Comparison is the base class and common API for all comparisons.
814
+
815
+ Args:
816
+ config_name (`str`):
817
+ This is used to define a hash specific to a comparison computation script and prevents the comparison's data
818
+ to be overridden when the comparison loading script is modified.
819
+ keep_in_memory (`bool`):
820
+ Keep all predictions and references in memory. Not possible in distributed settings.
821
+ cache_dir (`str`):
822
+ Path to a directory in which temporary prediction/references data will be stored.
823
+ The data directory should be located on a shared file-system in distributed setups.
824
+ num_process (`int`):
825
+ Specify the total number of nodes in a distributed settings.
826
+ This is useful to compute comparisons in distributed setups (in particular non-additive comparisons).
827
+ process_id (`int`):
828
+ Specify the id of the current process in a distributed setup (between 0 and num_process-1)
829
+ This is useful to compute comparisons in distributed setups (in particular non-additive comparisons).
830
+ seed (`int`, *optional*):
831
+ If specified, this will temporarily set numpy's random seed when [`~evaluate.Comparison.compute`] is run.
832
+ experiment_id (`str`):
833
+ A specific experiment id. This is used if several distributed evaluations share the same file system.
834
+ This is useful to compute comparisons in distributed setups (in particular non-additive comparisons).
835
+ max_concurrent_cache_files (`int`):
836
+ Max number of concurrent comparison cache files (default `10000`).
837
+ timeout (`Union[int, float]`):
838
+ Timeout in second for distributed setting synchronization.
839
+ """
840
+
841
+
842
+ class Measurement(EvaluationModule):
843
+ """A Measurement is the base class and common API for all measurements.
844
+
845
+ Args:
846
+ config_name (`str`):
847
+ This is used to define a hash specific to a measurement computation script and prevents the measurement's data
848
+ to be overridden when the measurement loading script is modified.
849
+ keep_in_memory (`bool`):
850
+ Keep all predictions and references in memory. Not possible in distributed settings.
851
+ cache_dir (`str`):
852
+ Path to a directory in which temporary prediction/references data will be stored.
853
+ The data directory should be located on a shared file-system in distributed setups.
854
+ num_process (`int`):
855
+ Specify the total number of nodes in a distributed settings.
856
+ This is useful to compute measurements in distributed setups (in particular non-additive measurements).
857
+ process_id (`int`):
858
+ Specify the id of the current process in a distributed setup (between 0 and num_process-1)
859
+ This is useful to compute measurements in distributed setups (in particular non-additive measurements).
860
+ seed (`int`, *optional*):
861
+ If specified, this will temporarily set numpy's random seed when [`~evaluate.Measurement.compute`] is run.
862
+ experiment_id (`str`):
863
+ A specific experiment id. This is used if several distributed evaluations share the same file system.
864
+ This is useful to compute measurements in distributed setups (in particular non-additive measurements).
865
+ max_concurrent_cache_files (`int`):
866
+ Max number of concurrent measurement cache files (default `10000`).
867
+ timeout (`Union[int, float]`):
868
+ Timeout in second for distributed setting synchronization.
869
+ """
870
+
871
+
872
+ class CombinedEvaluations:
873
+ def __init__(self, evaluation_modules, force_prefix=False):
874
+ from .loading import load # avoid circular imports
875
+
876
+ self.evaluation_module_names = None
877
+ if isinstance(evaluation_modules, list):
878
+ self.evaluation_modules = evaluation_modules
879
+ elif isinstance(evaluation_modules, dict):
880
+ self.evaluation_modules = list(evaluation_modules.values())
881
+ self.evaluation_module_names = list(evaluation_modules.keys())
882
+ loaded_modules = []
883
+
884
+ for module in self.evaluation_modules:
885
+ if isinstance(module, str):
886
+ module = load(module)
887
+ loaded_modules.append(module)
888
+ self.evaluation_modules = loaded_modules
889
+
890
+ if self.evaluation_module_names is None:
891
+ self.evaluation_module_names = [module.name for module in self.evaluation_modules]
892
+
893
+ self.force_prefix = force_prefix
894
+
895
+ def add(self, prediction=None, reference=None, **kwargs):
896
+ """Add one prediction and reference for each evaluation module's stack.
897
+
898
+ Args:
899
+ predictions (`list/array/tensor`, *optional*):
900
+ Predictions.
901
+ references (`list/array/tensor`, *optional*):
902
+ References.
903
+
904
+ Example:
905
+
906
+ ```py
907
+ >>> import evaluate
908
+ >>> accuracy = evaluate.load("accuracy")
909
+ >>> f1 = evaluate.load("f1")
910
+ >>> clf_metrics = combine(["accuracy", "f1"])
911
+ >>> for ref, pred in zip([0,1,0,1], [1,0,0,1]):
912
+ ... clf_metrics.add(references=ref, predictions=pred)
913
+ ```
914
+ """
915
+ for evaluation_module in self.evaluation_modules:
916
+ batch = {"predictions": prediction, "references": reference, **kwargs}
917
+ batch = {input_name: batch[input_name] for input_name in evaluation_module._feature_names()}
918
+ evaluation_module.add(**batch)
919
+
920
+ def add_batch(self, predictions=None, references=None, **kwargs):
921
+ """Add a batch of predictions and references for each evaluation module's stack.
922
+
923
+ Args:
924
+ predictions (`list/array/tensor`, *optional*):
925
+ Predictions.
926
+ references (`list/array/tensor`, *optional*):
927
+ References.
928
+
929
+ Example:
930
+ ```py
931
+ >>> import evaluate
932
+ >>> accuracy = evaluate.load("accuracy")
933
+ >>> f1 = evaluate.load("f1")
934
+ >>> clf_metrics = combine(["accuracy", "f1"])
935
+ >>> for refs, preds in zip([[0,1],[0,1]], [[1,0],[0,1]]):
936
+ ... clf_metrics.add(references=refs, predictions=preds)
937
+ ```
938
+ """
939
+ for evaluation_module in self.evaluation_modules:
940
+ batch = {"predictions": predictions, "references": references, **kwargs}
941
+ batch = {input_name: batch[input_name] for input_name in evaluation_module._feature_names()}
942
+ evaluation_module.add_batch(**batch)
943
+
944
+ def compute(self, predictions=None, references=None, **kwargs):
945
+ """Compute each evaluation module.
946
+
947
+ Usage of positional arguments is not allowed to prevent mistakes.
948
+
949
+ Args:
950
+ predictions (`list/array/tensor`, *optional*):
951
+ Predictions.
952
+ references (`list/array/tensor`, *optional*):
953
+ References.
954
+ **kwargs (*optional*):
955
+ Keyword arguments that will be forwarded to the evaluation module [`~evaluate.EvaluationModule.compute`]
956
+ method (see details in the docstring).
957
+
958
+ Return:
959
+ `dict` or `None`
960
+
961
+ - Dictionary with the results if this evaluation module is run on the main process (`process_id == 0`).
962
+ - `None` if the evaluation module is not run on the main process (`process_id != 0`).
963
+
964
+ Example:
965
+
966
+ ```py
967
+ >>> import evaluate
968
+ >>> accuracy = evaluate.load("accuracy")
969
+ >>> f1 = evaluate.load("f1")
970
+ >>> clf_metrics = combine(["accuracy", "f1"])
971
+ >>> clf_metrics.compute(predictions=[0,1], references=[1,1])
972
+ {'accuracy': 0.5, 'f1': 0.6666666666666666}
973
+ ```
974
+ """
975
+ results = []
976
+
977
+ for evaluation_module in self.evaluation_modules:
978
+ batch = {"predictions": predictions, "references": references, **kwargs}
979
+ results.append(evaluation_module.compute(**batch))
980
+
981
+ return self._merge_results(results)
982
+
983
+ def _merge_results(self, results):
984
+ merged_results = {}
985
+ results_keys = list(itertools.chain.from_iterable([r.keys() for r in results]))
986
+ duplicate_keys = {item for item, count in collections.Counter(results_keys).items() if count > 1}
987
+
988
+ duplicate_names = [
989
+ item for item, count in collections.Counter(self.evaluation_module_names).items() if count > 1
990
+ ]
991
+ duplicate_counter = {name: 0 for name in duplicate_names}
992
+
993
+ for module_name, result in zip(self.evaluation_module_names, results):
994
+ for k, v in result.items():
995
+ if k not in duplicate_keys and not self.force_prefix:
996
+ merged_results[f"{k}"] = v
997
+ elif module_name in duplicate_counter:
998
+ merged_results[f"{module_name}_{duplicate_counter[module_name]}_{k}"] = v
999
+ else:
1000
+ merged_results[f"{module_name}_{k}"] = v
1001
+
1002
+ if module_name in duplicate_counter:
1003
+ duplicate_counter[module_name] += 1
1004
+
1005
+ return merged_results
1006
+
1007
+
1008
+ def combine(evaluations, force_prefix=False):
1009
+ """Combines several metrics, comparisons, or measurements into a single `CombinedEvaluations` object that
1010
+ can be used like a single evaluation module.
1011
+
1012
+ If two scores have the same name, then they are prefixed with their module names.
1013
+ And if two modules have the same name, please use a dictionary to give them different names, otherwise an integer id is appended to the prefix.
1014
+
1015
+ Args:
1016
+ evaluations (`Union[list, dict]`):
1017
+ A list or dictionary of evaluation modules. The modules can either be passed
1018
+ as strings or loaded `EvaluationModule`s. If a dictionary is passed its keys are the names used and the values the modules.
1019
+ The names are used as prefix in case there are name overlaps in the returned results of each module or if `force_prefix=True`.
1020
+ force_prefix (`bool`, *optional*, defaults to `False`):
1021
+ If `True` all scores from the modules are prefixed with their name. If
1022
+ a dictionary is passed the keys are used as name otherwise the module's name.
1023
+
1024
+ Examples:
1025
+
1026
+ ```py
1027
+ >>> import evaluate
1028
+ >>> accuracy = evaluate.load("accuracy")
1029
+ >>> f1 = evaluate.load("f1")
1030
+ >>> clf_metrics = combine(["accuracy", "f1"])
1031
+ ```
1032
+ """
1033
+
1034
+ return CombinedEvaluations(evaluations, force_prefix=force_prefix)
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/saving.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import subprocess
4
+ import sys
5
+ from datetime import datetime
6
+ from pathlib import Path
7
+
8
+ from datasets.utils.filelock import FileLock
9
+
10
+ from . import __version__
11
+
12
+
13
+ def save(path_or_file, **data):
14
+ """
15
+ Saves results to a JSON file. Also saves system information such as current time, current commit
16
+ hash if inside a repository, and Python system information.
17
+
18
+ Args:
19
+ path_or_file (`str`):
20
+ Path or file to store the file. If only a folder is provided
21
+ the results file will be saved in the format `"result-%Y_%m_%d-%H_%M_%S.json"`.
22
+
23
+ Example:
24
+ ```py
25
+ >>> import evaluate
26
+ >>> result = {"bleu": 0.7}
27
+ >>> params = {"model": "gpt-2"}
28
+ >>> evaluate.save("./results/", **result, **params)
29
+ ```
30
+ """
31
+ current_time = datetime.now()
32
+
33
+ file_path = _setup_path(path_or_file, current_time)
34
+
35
+ data["_timestamp"] = current_time.isoformat()
36
+ data["_git_commit_hash"] = _git_commit_hash()
37
+ data["_evaluate_version"] = __version__
38
+ data["_python_version"] = sys.version
39
+ data["_interpreter_path"] = sys.executable
40
+
41
+ with FileLock(str(file_path) + ".lock"):
42
+ with open(file_path, "w") as f:
43
+ json.dump(data, f)
44
+
45
+ # cleanup lock file
46
+ try:
47
+ os.remove(str(file_path) + ".lock")
48
+ except FileNotFoundError:
49
+ pass
50
+
51
+ return file_path
52
+
53
+
54
+ def _setup_path(path_or_file, current_time):
55
+ path_or_file = Path(path_or_file)
56
+ is_file = len(path_or_file.suffix) > 0
57
+ if is_file:
58
+ folder = path_or_file.parent
59
+ file_name = path_or_file.name
60
+ else:
61
+ folder = path_or_file
62
+ file_name = "result-" + current_time.strftime("%Y_%m_%d-%H_%M_%S") + ".json"
63
+ folder.mkdir(parents=True, exist_ok=True)
64
+ return folder / file_name
65
+
66
+
67
+ def _git_commit_hash():
68
+ res = subprocess.run("git rev-parse --is-inside-work-tree".split(), cwd="./", stdout=subprocess.PIPE)
69
+ if res.stdout.decode().strip() == "true":
70
+ res = subprocess.run("git rev-parse HEAD".split(), cwd=os.getcwd(), stdout=subprocess.PIPE)
71
+ return res.stdout.decode().strip()
72
+ else:
73
+ return None