BryanW commited on
Commit
5e74fae
·
verified ·
1 Parent(s): c9c6027

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/Dream/Dream_Prism/eval_instruct/lm_eval/api/__init__.py +0 -0
  2. Prism/Dream/Dream_Prism/eval_instruct/lm_eval/api/instance.py +38 -0
  3. Prism/Dream/Dream_Prism/eval_instruct/lm_eval/api/metrics.py +578 -0
  4. Prism/Dream/Dream_Prism/eval_instruct/lm_eval/api/registry.py +196 -0
  5. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate-1.12.0.dist-info/licenses/LICENSE +201 -0
  6. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/_winconsole.cpython-312.pyc +0 -0
  7. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/exceptions.cpython-312.pyc +0 -0
  8. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/parser.cpython-312.pyc +0 -0
  9. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/termui.cpython-312.pyc +0 -0
  10. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/testing.cpython-312.pyc +0 -0
  11. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/__pycache__/_version.cpython-312.pyc +0 -0
  12. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/__pycache__/relativedelta.cpython-312.pyc +0 -0
  13. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/__pycache__/rrule.cpython-312.pyc +0 -0
  14. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/__init__.py +12 -0
  15. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/_common.py +419 -0
  16. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/_factories.py +80 -0
  17. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/tz.py +1849 -0
  18. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/win.py +370 -0
  19. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/zoneinfo/__init__.py +167 -0
  20. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/__init__.cpython-312.pyc +0 -0
  21. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/config.cpython-312.pyc +0 -0
  22. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/hub.cpython-312.pyc +0 -0
  23. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/info.cpython-312.pyc +0 -0
  24. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/inspect.cpython-312.pyc +0 -0
  25. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/loading.cpython-312.pyc +0 -0
  26. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/module.cpython-312.pyc +0 -0
  27. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/naming.cpython-312.pyc +0 -0
  28. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/saving.cpython-312.pyc +0 -0
  29. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/visualization.cpython-312.pyc +0 -0
  30. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/commands/__init__.py +0 -0
  31. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/commands/__pycache__/__init__.cpython-312.pyc +0 -0
  32. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/commands/__pycache__/evaluate_cli.cpython-312.pyc +0 -0
  33. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/commands/evaluate_cli.py +137 -0
  34. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluation_suite/__pycache__/__init__.cpython-312.pyc +0 -0
  35. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__init__.py +140 -0
  36. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/__init__.cpython-312.pyc +0 -0
  37. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/audio_classification.cpython-312.pyc +0 -0
  38. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/automatic_speech_recognition.cpython-312.pyc +0 -0
  39. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/base.cpython-312.pyc +0 -0
  40. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/image_classification.cpython-312.pyc +0 -0
  41. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/question_answering.cpython-312.pyc +0 -0
  42. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/text2text_generation.cpython-312.pyc +0 -0
  43. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/text_classification.cpython-312.pyc +0 -0
  44. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/text_generation.cpython-312.pyc +0 -0
  45. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/token_classification.cpython-312.pyc +0 -0
  46. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
  47. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/audio_classification.py +151 -0
  48. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/automatic_speech_recognition.py +112 -0
  49. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/base.py +544 -0
  50. Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/image_classification.py +119 -0
Prism/Dream/Dream_Prism/eval_instruct/lm_eval/api/__init__.py ADDED
File without changes
Prism/Dream/Dream_Prism/eval_instruct/lm_eval/api/instance.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass, field
2
+ from typing import Literal, Optional, Tuple
3
+
4
+
5
+ OutputType = Literal[
6
+ "loglikelihood", "loglikelihood_rolling", "generate_until", "multiple_choice"
7
+ ]
8
+
9
+
10
+ @dataclass
11
+ class Instance:
12
+ request_type: OutputType
13
+ doc: dict
14
+ arguments: tuple
15
+ idx: int
16
+ metadata: Tuple[Optional[str], Optional[int], Optional[int]] = field(
17
+ default_factory=lambda: (None, None, None)
18
+ )
19
+ resps: list = field(default_factory=list)
20
+ filtered_resps: dict = field(default_factory=dict)
21
+
22
+ # initialized after init
23
+ task_name: Optional[str] = None
24
+ doc_id: Optional[int] = None
25
+ repeats: Optional[int] = None
26
+
27
+ def __post_init__(self) -> None:
28
+ # unpack metadata field
29
+ self.task_name, self.doc_id, self.repeats = self.metadata
30
+
31
+ @property
32
+ def args(self):
33
+ """
34
+ Returns (string,) where `string` is the string to calculate loglikelihood over
35
+ """
36
+ return (
37
+ self.arguments if isinstance(self.arguments, tuple) else (self.arguments,)
38
+ )
Prism/Dream/Dream_Prism/eval_instruct/lm_eval/api/metrics.py ADDED
@@ -0,0 +1,578 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import math
3
+ import random
4
+ import re
5
+ import string
6
+ from collections.abc import Iterable
7
+ from typing import List
8
+
9
+ import numpy as np
10
+ import sacrebleu
11
+
12
+ from lm_eval.api.registry import register_aggregation, register_metric
13
+
14
+
15
+ eval_logger = logging.getLogger(__name__)
16
+
17
+
18
+ # Register Aggregations First
19
+ @register_aggregation("bypass")
20
+ def bypass_agg(arr):
21
+ return 999
22
+
23
+
24
+ @register_aggregation("nanmean")
25
+ def nanmean(arr):
26
+ if len(arr) == 0 or all(np.isnan(arr)):
27
+ return np.nan
28
+ return np.nanmean(arr)
29
+
30
+
31
+ @register_aggregation("mean")
32
+ def mean(arr):
33
+ return sum(arr) / len(arr)
34
+
35
+
36
+ @register_aggregation("median")
37
+ def median(arr):
38
+ return arr[len(arr) // 2]
39
+
40
+
41
+ # Certain metrics must be calculated across all documents in a benchmark.
42
+ # We use them as aggregation metrics, paired with no-op passthrough metric fns.
43
+ @register_aggregation("perplexity")
44
+ def perplexity(items):
45
+ return math.exp(-mean(items))
46
+
47
+
48
+ @register_aggregation("weighted_perplexity")
49
+ def weighted_perplexity(items):
50
+ return math.exp(-weighted_mean(items))
51
+
52
+
53
+ @register_aggregation("bits_per_byte")
54
+ def bits_per_byte(items):
55
+ return -weighted_mean(items) / math.log(2)
56
+
57
+
58
+ @register_aggregation("f1")
59
+ def f1_score(items):
60
+ from sklearn.metrics import f1_score
61
+
62
+ unzipped_list = list(zip(*items))
63
+ golds = unzipped_list[0]
64
+ preds = unzipped_list[1]
65
+ fscore = f1_score(golds, preds)
66
+
67
+ return np.max(fscore)
68
+
69
+
70
+ @register_aggregation("matthews_corrcoef")
71
+ def matthews_corrcoef(items):
72
+ from sklearn.metrics import matthews_corrcoef
73
+
74
+ unzipped_list = list(zip(*items))
75
+ golds = unzipped_list[0]
76
+ preds = unzipped_list[1]
77
+ return matthews_corrcoef(golds, preds)
78
+
79
+
80
+ @register_aggregation("bleu")
81
+ def bleu(items):
82
+ """The Bilingual Evaluation Understudy Score, or BLEU for short, is a metric
83
+ for evaluating a generated sentence to a reference sentence. It counts matching
84
+ n-grams in the candidate translation to n-grams in the reference text, where
85
+ 1-gram or unigram would be each token and a bigram comparison would be each
86
+ word pair. The comparison is made regardless of word order
87
+ Source: https://machinelearningmastery.com/calculate-bleu-score-for-text-python/
88
+ Paper: https://www.aclweb.org/anthology/P02-1040/
89
+
90
+ Higher is better
91
+ """
92
+ refs = list(zip(*items))[0]
93
+ preds = list(zip(*items))[1]
94
+ refs, preds = _sacreformat(refs, preds)
95
+ return sacrebleu.corpus_bleu(preds, refs).score
96
+
97
+
98
+ @register_aggregation("chrf")
99
+ def chrf(items):
100
+ """chrF++ is a tool for automatic evaluation of machine translation output
101
+ based on character n-gram precision and recall enhanced with word n-grams.
102
+ Source: https://github.com/m-popovic/chrF
103
+ Paper: https://www.aclweb.org/anthology/W15-3049.pdf
104
+
105
+ Higher is better # TODO I think
106
+ """
107
+ refs = list(zip(*items))[0]
108
+ preds = list(zip(*items))[1]
109
+ refs, preds = _sacreformat(refs, preds)
110
+ return sacrebleu.corpus_chrf(preds, refs).score
111
+
112
+
113
+ @register_aggregation("ter")
114
+ def ter(items):
115
+ """Translation Error Rate is an error metric for machine translation that
116
+ measures the number of edits required to change a system output into one
117
+ of the references
118
+ Source: http://www.cs.umd.edu/~snover/tercom/
119
+ Paper: http://mt-archive.info/AMTA-2006-Snover.pdf
120
+
121
+ Lower is better
122
+ """
123
+ refs = list(zip(*items))[0]
124
+ preds = list(zip(*items))[1]
125
+ refs, preds = _sacreformat(refs, preds)
126
+ return sacrebleu.corpus_ter(preds, refs).score
127
+
128
+
129
+ @register_aggregation("brier_score")
130
+ def brier_score(items): # This is a passthrough function
131
+ gold, predictions = list(zip(*items))
132
+ bs, num_class = np.array(predictions).shape
133
+
134
+ gold = list(gold)
135
+ gold_one_hot = np.eye(num_class)[gold]
136
+ return np.mean(np.sum((predictions - gold_one_hot) ** 2, axis=1))
137
+
138
+
139
+ @register_metric(
140
+ metric="brier_score",
141
+ higher_is_better=False,
142
+ output_type=["multiple_choice"],
143
+ aggregation="brier_score",
144
+ )
145
+ def brier_score_fn(items): # This is a passthrough function
146
+ return items
147
+
148
+
149
+ @register_metric(
150
+ metric="acc",
151
+ higher_is_better=True,
152
+ output_type=["loglikelihood", "multiple_choice"],
153
+ aggregation="mean",
154
+ )
155
+ def acc_fn(items): # This is a passthrough function
156
+ return items
157
+
158
+
159
+ @register_metric(
160
+ metric="acc_norm",
161
+ higher_is_better=True,
162
+ output_type=["loglikelihood", "multiple_choice"],
163
+ aggregation="mean",
164
+ )
165
+ def acc_norm_fn(items): # This is a passthrough function
166
+ return items
167
+
168
+
169
+ @register_metric(
170
+ metric="acc_mutual_info",
171
+ higher_is_better=True,
172
+ output_type="multiple_choice",
173
+ aggregation="mean",
174
+ )
175
+ def acc_mutual_info_fn(items): # This is a passthrough function
176
+ return items
177
+
178
+
179
+ ### the code used in the `exact_match_hf_evaluate` function is ported from
180
+ ### https://github.com/huggingface/evaluate/blob/main/metrics/exact_match/exact_match.py
181
+ ### which is under the apache license.
182
+
183
+ # Copyright 2020 The HuggingFace Datasets Authors and the current dataset script contributor.
184
+
185
+ # Licensed under the Apache License, Version 2.0 (the "License");
186
+ # you may not use this file except in compliance with the License.
187
+ # You may obtain a copy of the License at
188
+
189
+ # http://www.apache.org/licenses/LICENSE-2.0
190
+
191
+
192
+ # Unless required by applicable law or agreed to in writing, software
193
+ # distributed under the License is distributed on an "AS IS" BASIS,
194
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
195
+ # See the License for the specific language governing permissions and
196
+ # limitations under the License.
197
+ def exact_match_hf_evaluate(
198
+ predictions,
199
+ references,
200
+ regexes_to_ignore=None,
201
+ ignore_case=False,
202
+ ignore_punctuation=False,
203
+ ignore_numbers=False,
204
+ ):
205
+ if regexes_to_ignore is not None:
206
+ for s in regexes_to_ignore:
207
+ predictions = np.array([re.sub(s, "", x) for x in predictions])
208
+ references = np.array([re.sub(s, "", x) for x in references])
209
+ else:
210
+ predictions = np.asarray(predictions)
211
+ references = np.asarray(references)
212
+
213
+ if ignore_case:
214
+ predictions = np.char.lower(predictions)
215
+ references = np.char.lower(references)
216
+
217
+ if ignore_punctuation:
218
+ repl_table = string.punctuation.maketrans("", "", string.punctuation)
219
+ predictions = np.char.translate(predictions, table=repl_table)
220
+ references = np.char.translate(references, table=repl_table)
221
+
222
+ if ignore_numbers:
223
+ repl_table = string.digits.maketrans("", "", string.digits)
224
+ predictions = np.char.translate(predictions, table=repl_table)
225
+ references = np.char.translate(references, table=repl_table)
226
+
227
+ score_list = predictions == references
228
+
229
+ return {"exact_match": np.mean(score_list)}
230
+
231
+
232
+ ###
233
+
234
+
235
+ @register_metric(
236
+ metric="exact_match",
237
+ higher_is_better=True,
238
+ output_type="generate_until",
239
+ aggregation="mean",
240
+ )
241
+ def exact_match_fn(**kwargs):
242
+ return exact_match_hf_evaluate(**kwargs)
243
+
244
+
245
+ @register_metric(
246
+ metric="perplexity",
247
+ higher_is_better=False,
248
+ output_type="loglikelihood",
249
+ aggregation="perplexity",
250
+ )
251
+ def perplexity_fn(items): # This is a passthrough function
252
+ return items
253
+
254
+
255
+ @register_metric(
256
+ metric="word_perplexity",
257
+ higher_is_better=False,
258
+ output_type="loglikelihood_rolling",
259
+ aggregation="weighted_perplexity",
260
+ )
261
+ def word_perplexity_fn(items): # This is a passthrough function
262
+ return items
263
+
264
+
265
+ @register_metric(
266
+ metric="byte_perplexity",
267
+ higher_is_better=False,
268
+ output_type="loglikelihood_rolling",
269
+ aggregation="weighted_perplexity",
270
+ )
271
+ def byte_perplexity_fn(items): # This is a passthrough function
272
+ return items
273
+
274
+
275
+ @register_metric(
276
+ metric="bits_per_byte",
277
+ higher_is_better=False,
278
+ output_type="loglikelihood_rolling",
279
+ aggregation="bits_per_byte",
280
+ )
281
+ def bits_per_byte_fn(items): # This is a passthrough function
282
+ return items
283
+
284
+
285
+ def pop_stddev(arr):
286
+ mu = mean(arr)
287
+ return math.sqrt(sum([(x - mu) ** 2 for x in arr]) / len(arr))
288
+
289
+
290
+ def sample_stddev(arr):
291
+ mu = mean(arr)
292
+ return math.sqrt(sum([(x - mu) ** 2 for x in arr]) / (len(arr) - 1))
293
+
294
+
295
+ def mean_stderr(arr):
296
+ return sample_stddev(arr) / math.sqrt(len(arr))
297
+
298
+
299
+ @register_metric(
300
+ metric="bypass",
301
+ higher_is_better=True,
302
+ output_type=["loglikelihood", "multiple_choice", "generate_until"],
303
+ aggregation="bypass",
304
+ )
305
+ def bypass(items):
306
+ return None
307
+
308
+
309
+ @register_metric(
310
+ metric="mcc",
311
+ higher_is_better=True,
312
+ output_type="multiple_choice",
313
+ aggregation="matthews_corrcoef",
314
+ )
315
+ def mcc_fn(items): # This is a passthrough function
316
+ return items
317
+
318
+
319
+ @register_metric(
320
+ metric="f1",
321
+ higher_is_better=True,
322
+ output_type="multiple_choice",
323
+ aggregation="f1",
324
+ )
325
+ def f1_fn(items): # This is a passthrough function
326
+ return items
327
+
328
+
329
+ @register_metric(
330
+ metric="bleu",
331
+ higher_is_better=True,
332
+ output_type="generate_until",
333
+ aggregation="bleu",
334
+ )
335
+ def bleu_fn(items): # This is a passthrough function
336
+ return items
337
+
338
+
339
+ @register_metric(
340
+ metric="chrf",
341
+ higher_is_better=True,
342
+ output_type="generate_until",
343
+ aggregation="chrf",
344
+ )
345
+ def chrf_fn(items): # This is a passthrough function
346
+ return items
347
+
348
+
349
+ @register_metric(
350
+ metric="ter",
351
+ higher_is_better=True,
352
+ output_type="generate_until",
353
+ aggregation="ter",
354
+ )
355
+ def ter_fn(items): # This is a passthrough function
356
+ return items
357
+
358
+
359
+ @register_metric(
360
+ metric="acc_all",
361
+ higher_is_better=True,
362
+ output_type="loglikelihood",
363
+ aggregation="mean",
364
+ )
365
+ def acc_all(items):
366
+ # Only count as correct if all answers are labeled correctly for each question
367
+ question_scoring_dict = {}
368
+ preds = list(zip(*items))[0]
369
+ docs = list(zip(*items))[1]
370
+
371
+ for doc, pred in zip(docs, preds):
372
+ paragraph_id = doc["idx"]["paragraph"]
373
+ question_id = doc["idx"]["question"]
374
+ if (paragraph_id, question_id) not in question_scoring_dict:
375
+ question_scoring_dict[(paragraph_id, question_id)] = []
376
+
377
+ gold_label = doc["label"] == 1
378
+
379
+ question_scoring_dict[(paragraph_id, question_id)].append(gold_label == pred)
380
+ acc = np.mean([int(all(x)) for x in question_scoring_dict.values()])
381
+ return acc
382
+
383
+
384
+ def acc_all_stderr(items):
385
+ # Only count as correct if all answers are labeled correctly for each question
386
+ question_scoring_dict = {}
387
+ preds = list(zip(*items))[0]
388
+ docs = list(zip(*items))[1]
389
+
390
+ for doc, pred in zip(docs, preds):
391
+ question_id = doc["idx"]["question"]
392
+ if question_id not in question_scoring_dict:
393
+ question_scoring_dict[question_id] = []
394
+
395
+ gold_label = doc["label"] == 1
396
+ question_scoring_dict[question_id].append(gold_label == pred)
397
+
398
+ acc = mean_stderr([int(all(x)) for x in question_scoring_dict.values()])
399
+ return acc
400
+
401
+
402
+ def metric_max_over_ground_truths(metric_fn, prediction, ground_truths):
403
+ """Compute max metric between prediction and each ground truth."""
404
+ scores_for_ground_truths = []
405
+ for ground_truth in ground_truths:
406
+ score = metric_fn(prediction, ground_truth)
407
+ scores_for_ground_truths.append(score)
408
+ return max(scores_for_ground_truths)
409
+
410
+
411
+ def weighted_mean(items):
412
+ a, b = zip(*items)
413
+ return sum(a) / sum(b)
414
+
415
+
416
+ def is_non_str_iterable(obj):
417
+ return isinstance(obj, Iterable) and not isinstance(obj, str)
418
+
419
+
420
+ def _sacreformat(refs, preds):
421
+ """Format refs and preds for sacrebleu corpus calculation. It is very particular"""
422
+ # Sacrebleu expects (List[str], List[List[str])
423
+ # e.g. sacrebleu.corpus_bleu([pred_t], [[ref1_stream], [ref2_stream], ...])
424
+
425
+ # Note [ref1_stream] is the first reference for each pred.
426
+ # So lists are size N and (M, N) for N preds and M possible refs for each pred
427
+ # This is a different order of dimensions that I would expect
428
+
429
+ # We expect refs to be List[str] or List[List[str]], the outer list corresponding to preds
430
+ # Must become List[List[str]] with the inner list corresponding to preds
431
+ if not is_non_str_iterable(refs):
432
+ refs = list(refs)
433
+ if not is_non_str_iterable(refs[0]):
434
+ refs = [[ref] for ref in refs]
435
+ refs = list(zip(*refs))
436
+ # Note the number of refs in each ref list much match the number of preds
437
+
438
+ # We expect preds to be List[str] or List[List[str]]. Must become List[str]
439
+ if not is_non_str_iterable(preds):
440
+ preds = list(preds)
441
+ if is_non_str_iterable(preds[0]):
442
+ assert len(preds[0]) == 1, f"Pred must be a str, was {preds[0]}"
443
+ preds = [pred[0] for pred in preds]
444
+
445
+ return refs, preds
446
+
447
+
448
+ # stderr stuff
449
+
450
+
451
+ class _bootstrap_internal:
452
+ def __init__(self, f, n) -> None:
453
+ self.f = f
454
+ self.n = n
455
+
456
+ def __call__(self, v):
457
+ i, xs = v
458
+ rnd = random.Random()
459
+ rnd.seed(i)
460
+ res = []
461
+ for _ in range(self.n):
462
+ res.append(self.f(rnd.choices(xs, k=len(xs))))
463
+ return res
464
+
465
+
466
+ def bootstrap_stderr(f, xs, iters):
467
+ import multiprocessing as mp
468
+
469
+ pool = mp.Pool(mp.cpu_count())
470
+ # this gives a biased estimate of the stderr (i.e w/ the mean, it gives something
471
+ # equivalent to stderr calculated without Bessel's correction in the stddev.
472
+ # Unfortunately, I haven't been able to figure out what the right correction is
473
+ # to make the bootstrap unbiased - i considered multiplying by sqrt(n/(n-1)) but
474
+ # that would be ad-hoc and I can't prove that that would actually be an unbiased estimator)
475
+ # Thankfully, shouldn't matter because our samples are pretty big usually anyways
476
+ res = []
477
+ chunk_size = min(1000, iters)
478
+ from tqdm import tqdm
479
+
480
+ print("bootstrapping for stddev:", f.__name__)
481
+ for bootstrap in tqdm(
482
+ pool.imap(
483
+ _bootstrap_internal(f, chunk_size),
484
+ [(i, xs) for i in range(iters // chunk_size)],
485
+ ),
486
+ total=iters // chunk_size,
487
+ ):
488
+ # sample w replacement
489
+ res.extend(bootstrap)
490
+
491
+ pool.close()
492
+ return sample_stddev(res)
493
+
494
+
495
+ def stderr_for_metric(metric, bootstrap_iters: int):
496
+ if bootstrap_iters <= 0:
497
+ # return no function (don't compute stderr) if bootstrap iters = 0
498
+ return None
499
+
500
+ bootstrappable = [
501
+ median,
502
+ matthews_corrcoef,
503
+ f1_score,
504
+ perplexity,
505
+ bleu,
506
+ chrf,
507
+ ter,
508
+ nanmean,
509
+ ]
510
+
511
+ if metric in bootstrappable:
512
+ return lambda x: bootstrap_stderr(metric, x, iters=bootstrap_iters)
513
+
514
+ stderr = {mean: mean_stderr, acc_all: acc_all_stderr}
515
+
516
+ return stderr.get(metric, None)
517
+
518
+
519
+ def pooled_sample_stderr(stderrs: List[float], sizes: List[int]):
520
+ # Used to aggregate bootstrapped stderrs across subtasks in a group,
521
+ # when we are weighting by the size of each subtask.
522
+ #
523
+
524
+ assert len(stderrs) == len(sizes)
525
+
526
+ # formula source: https://en.wikipedia.org/wiki/Pooled_variance
527
+ # and: https://stats.stackexchange.com/a/4841331
528
+ # this empirically seems to match running `stderr_for_metric` on all instances
529
+ # from the subtasks concatenated with each other.
530
+ pooled_sample_var = (
531
+ sum([(size - 1) * stderr**2 * size for size, stderr in zip(sizes, stderrs)])
532
+ ) / (sum(sizes) - len(sizes))
533
+
534
+ return np.sqrt(pooled_sample_var / sum(sizes))
535
+
536
+
537
+ def combined_sample_stderr(stderrs: List[float], sizes: List[int], metrics=None):
538
+ assert metrics is not None, (
539
+ "Need to pass a list of each subtask's metric for this stderr aggregation"
540
+ )
541
+ assert len(stderrs) == len(sizes) and len(sizes) == len(metrics)
542
+
543
+ # See https://github.com/EleutherAI/lm-evaluation-harness/pull/1390 for more documentation.
544
+ # This formula depends on sample means.
545
+ # removed because it seems to give erroneously huge stderrs for groupings of tasks
546
+ # and does not seem to match up with bootstrap-calculated stderrs for groups.
547
+
548
+ ### don't use this unless a statistician has told you it's the right thing to do ###
549
+
550
+ # accumulators: we'll aggregate pairwise N - 1 times
551
+ variance = stderrs[0] ** 2
552
+ curr_size = sizes[0]
553
+ curr_score = metrics[0]
554
+
555
+ for stderr, size, score in zip(stderrs[1:], sizes[1:], metrics[1:]):
556
+ curr_score = ((curr_score * curr_size) + (score * size)) / (
557
+ curr_size + size
558
+ ) # NOTE: this assumes our aggregation fn is "mean"
559
+
560
+ variance = ((curr_size - 1) * variance + (size - 1) * (stderr**2)) / (
561
+ curr_size + size - 1
562
+ ) + curr_size * size / ((curr_size + size) * (curr_size + size - 1)) * (
563
+ curr_score - score
564
+ ) ** 2
565
+
566
+ return np.sqrt(variance)
567
+
568
+
569
+ def aggregate_subtask_metrics(metrics, sizes, weight_by_size=True):
570
+ # A helper function that is used to aggregate
571
+ # subtask scores cross-task.
572
+ # TODO: does not hold for non-mean aggregations
573
+ if not weight_by_size:
574
+ sizes = [1] * len(sizes)
575
+
576
+ assert len(metrics) == len(sizes)
577
+
578
+ return sum([metric * size for metric, size in zip(metrics, sizes)]) / sum(sizes)
Prism/Dream/Dream_Prism/eval_instruct/lm_eval/api/registry.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from typing import Callable, Dict, Union
3
+
4
+ import evaluate as hf_evaluate
5
+
6
+ from lm_eval.api.model import LM
7
+
8
+
9
+ eval_logger = logging.getLogger(__name__)
10
+
11
+ MODEL_REGISTRY = {}
12
+
13
+
14
+ def register_model(*names):
15
+ # either pass a list or a single alias.
16
+ # function receives them as a tuple of strings
17
+
18
+ def decorate(cls):
19
+ for name in names:
20
+ assert issubclass(cls, LM), (
21
+ f"Model '{name}' ({cls.__name__}) must extend LM class"
22
+ )
23
+
24
+ assert name not in MODEL_REGISTRY, (
25
+ f"Model named '{name}' conflicts with existing model! Please register with a non-conflicting alias instead."
26
+ )
27
+
28
+ MODEL_REGISTRY[name] = cls
29
+ return cls
30
+
31
+ return decorate
32
+
33
+
34
+ def get_model(model_name):
35
+ try:
36
+ return MODEL_REGISTRY[model_name]
37
+ except KeyError:
38
+ raise ValueError(
39
+ f"Attempted to load model '{model_name}', but no model for this name found! Supported model names: {', '.join(MODEL_REGISTRY.keys())}"
40
+ )
41
+
42
+
43
+ TASK_REGISTRY = {}
44
+ GROUP_REGISTRY = {}
45
+ ALL_TASKS = set()
46
+ func2task_index = {}
47
+
48
+
49
+ def register_task(name):
50
+ def decorate(fn):
51
+ assert name not in TASK_REGISTRY, (
52
+ f"task named '{name}' conflicts with existing registered task!"
53
+ )
54
+
55
+ TASK_REGISTRY[name] = fn
56
+ ALL_TASKS.add(name)
57
+ func2task_index[fn.__name__] = name
58
+ return fn
59
+
60
+ return decorate
61
+
62
+
63
+ def register_group(name):
64
+ def decorate(fn):
65
+ func_name = func2task_index[fn.__name__]
66
+ if name in GROUP_REGISTRY:
67
+ GROUP_REGISTRY[name].append(func_name)
68
+ else:
69
+ GROUP_REGISTRY[name] = [func_name]
70
+ ALL_TASKS.add(name)
71
+ return fn
72
+
73
+ return decorate
74
+
75
+
76
+ OUTPUT_TYPE_REGISTRY = {}
77
+ METRIC_REGISTRY = {}
78
+ METRIC_AGGREGATION_REGISTRY = {}
79
+ AGGREGATION_REGISTRY: Dict[str, Callable[[], Dict[str, Callable]]] = {}
80
+ HIGHER_IS_BETTER_REGISTRY = {}
81
+ FILTER_REGISTRY = {}
82
+
83
+ DEFAULT_METRIC_REGISTRY = {
84
+ "loglikelihood": [
85
+ "perplexity",
86
+ "acc",
87
+ ],
88
+ "loglikelihood_rolling": ["word_perplexity", "byte_perplexity", "bits_per_byte"],
89
+ "multiple_choice": ["acc", "acc_norm"],
90
+ "generate_until": ["exact_match"],
91
+ }
92
+
93
+
94
+ def register_metric(**args):
95
+ # TODO: do we want to enforce a certain interface to registered metrics?
96
+ def decorate(fn):
97
+ assert "metric" in args
98
+ name = args["metric"]
99
+
100
+ for key, registry in [
101
+ ("metric", METRIC_REGISTRY),
102
+ ("higher_is_better", HIGHER_IS_BETTER_REGISTRY),
103
+ ("aggregation", METRIC_AGGREGATION_REGISTRY),
104
+ ]:
105
+ if key in args:
106
+ value = args[key]
107
+ assert value not in registry, (
108
+ f"{key} named '{value}' conflicts with existing registered {key}!"
109
+ )
110
+
111
+ if key == "metric":
112
+ registry[name] = fn
113
+ elif key == "aggregation":
114
+ registry[name] = AGGREGATION_REGISTRY[value]
115
+ else:
116
+ registry[name] = value
117
+
118
+ return fn
119
+
120
+ return decorate
121
+
122
+
123
+ def get_metric(name: str, hf_evaluate_metric=False) -> Callable:
124
+ if not hf_evaluate_metric:
125
+ if name in METRIC_REGISTRY:
126
+ return METRIC_REGISTRY[name]
127
+ else:
128
+ eval_logger.warning(
129
+ f"Could not find registered metric '{name}' in lm-eval, searching in HF Evaluate library..."
130
+ )
131
+
132
+ try:
133
+ metric_object = hf_evaluate.load(name)
134
+ return metric_object.compute
135
+ except Exception:
136
+ eval_logger.error(
137
+ f"{name} not found in the evaluate library! Please check https://huggingface.co/evaluate-metric",
138
+ )
139
+
140
+
141
+ def register_aggregation(name: str):
142
+ def decorate(fn):
143
+ assert name not in AGGREGATION_REGISTRY, (
144
+ f"aggregation named '{name}' conflicts with existing registered aggregation!"
145
+ )
146
+
147
+ AGGREGATION_REGISTRY[name] = fn
148
+ return fn
149
+
150
+ return decorate
151
+
152
+
153
+ def get_aggregation(name: str) -> Callable[[], Dict[str, Callable]]:
154
+ try:
155
+ return AGGREGATION_REGISTRY[name]
156
+ except KeyError:
157
+ eval_logger.warning(f"{name} not a registered aggregation metric!")
158
+
159
+
160
+ def get_metric_aggregation(name: str) -> Callable[[], Dict[str, Callable]]:
161
+ try:
162
+ return METRIC_AGGREGATION_REGISTRY[name]
163
+ except KeyError:
164
+ eval_logger.warning(f"{name} metric is not assigned a default aggregation!")
165
+
166
+
167
+ def is_higher_better(metric_name) -> bool:
168
+ try:
169
+ return HIGHER_IS_BETTER_REGISTRY[metric_name]
170
+ except KeyError:
171
+ eval_logger.warning(
172
+ f"higher_is_better not specified for metric '{metric_name}'!"
173
+ )
174
+
175
+
176
+ def register_filter(name):
177
+ def decorate(cls):
178
+ if name in FILTER_REGISTRY:
179
+ eval_logger.info(
180
+ f"Registering filter `{name}` that is already in Registry {FILTER_REGISTRY}"
181
+ )
182
+ FILTER_REGISTRY[name] = cls
183
+ return cls
184
+
185
+ return decorate
186
+
187
+
188
+ def get_filter(filter_name: Union[str, Callable]) -> Callable:
189
+ try:
190
+ return FILTER_REGISTRY[filter_name]
191
+ except KeyError as e:
192
+ if callable(filter_name):
193
+ return filter_name
194
+ else:
195
+ eval_logger.warning(f"filter `{filter_name}` is not registered!")
196
+ raise e
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/accelerate-1.12.0.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/_winconsole.cpython-312.pyc ADDED
Binary file (12 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/exceptions.cpython-312.pyc ADDED
Binary file (14.9 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/parser.cpython-312.pyc ADDED
Binary file (21.5 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/termui.cpython-312.pyc ADDED
Binary file (32.8 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/click/__pycache__/testing.cpython-312.pyc ADDED
Binary file (24.8 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/__pycache__/_version.cpython-312.pyc ADDED
Binary file (336 Bytes). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/__pycache__/relativedelta.cpython-312.pyc ADDED
Binary file (28.4 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/__pycache__/rrule.cpython-312.pyc ADDED
Binary file (69.3 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/__init__.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ from .tz import *
3
+ from .tz import __doc__
4
+
5
+ __all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
6
+ "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz",
7
+ "enfold", "datetime_ambiguous", "datetime_exists",
8
+ "resolve_imaginary", "UTC", "DeprecatedTzFormatWarning"]
9
+
10
+
11
+ class DeprecatedTzFormatWarning(Warning):
12
+ """Warning raised when time zones are parsed from deprecated formats."""
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/_common.py ADDED
@@ -0,0 +1,419 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from six import PY2
2
+
3
+ from functools import wraps
4
+
5
+ from datetime import datetime, timedelta, tzinfo
6
+
7
+
8
+ ZERO = timedelta(0)
9
+
10
+ __all__ = ['tzname_in_python2', 'enfold']
11
+
12
+
13
+ def tzname_in_python2(namefunc):
14
+ """Change unicode output into bytestrings in Python 2
15
+
16
+ tzname() API changed in Python 3. It used to return bytes, but was changed
17
+ to unicode strings
18
+ """
19
+ if PY2:
20
+ @wraps(namefunc)
21
+ def adjust_encoding(*args, **kwargs):
22
+ name = namefunc(*args, **kwargs)
23
+ if name is not None:
24
+ name = name.encode()
25
+
26
+ return name
27
+
28
+ return adjust_encoding
29
+ else:
30
+ return namefunc
31
+
32
+
33
+ # The following is adapted from Alexander Belopolsky's tz library
34
+ # https://github.com/abalkin/tz
35
+ if hasattr(datetime, 'fold'):
36
+ # This is the pre-python 3.6 fold situation
37
+ def enfold(dt, fold=1):
38
+ """
39
+ Provides a unified interface for assigning the ``fold`` attribute to
40
+ datetimes both before and after the implementation of PEP-495.
41
+
42
+ :param fold:
43
+ The value for the ``fold`` attribute in the returned datetime. This
44
+ should be either 0 or 1.
45
+
46
+ :return:
47
+ Returns an object for which ``getattr(dt, 'fold', 0)`` returns
48
+ ``fold`` for all versions of Python. In versions prior to
49
+ Python 3.6, this is a ``_DatetimeWithFold`` object, which is a
50
+ subclass of :py:class:`datetime.datetime` with the ``fold``
51
+ attribute added, if ``fold`` is 1.
52
+
53
+ .. versionadded:: 2.6.0
54
+ """
55
+ return dt.replace(fold=fold)
56
+
57
+ else:
58
+ class _DatetimeWithFold(datetime):
59
+ """
60
+ This is a class designed to provide a PEP 495-compliant interface for
61
+ Python versions before 3.6. It is used only for dates in a fold, so
62
+ the ``fold`` attribute is fixed at ``1``.
63
+
64
+ .. versionadded:: 2.6.0
65
+ """
66
+ __slots__ = ()
67
+
68
+ def replace(self, *args, **kwargs):
69
+ """
70
+ Return a datetime with the same attributes, except for those
71
+ attributes given new values by whichever keyword arguments are
72
+ specified. Note that tzinfo=None can be specified to create a naive
73
+ datetime from an aware datetime with no conversion of date and time
74
+ data.
75
+
76
+ This is reimplemented in ``_DatetimeWithFold`` because pypy3 will
77
+ return a ``datetime.datetime`` even if ``fold`` is unchanged.
78
+ """
79
+ argnames = (
80
+ 'year', 'month', 'day', 'hour', 'minute', 'second',
81
+ 'microsecond', 'tzinfo'
82
+ )
83
+
84
+ for arg, argname in zip(args, argnames):
85
+ if argname in kwargs:
86
+ raise TypeError('Duplicate argument: {}'.format(argname))
87
+
88
+ kwargs[argname] = arg
89
+
90
+ for argname in argnames:
91
+ if argname not in kwargs:
92
+ kwargs[argname] = getattr(self, argname)
93
+
94
+ dt_class = self.__class__ if kwargs.get('fold', 1) else datetime
95
+
96
+ return dt_class(**kwargs)
97
+
98
+ @property
99
+ def fold(self):
100
+ return 1
101
+
102
+ def enfold(dt, fold=1):
103
+ """
104
+ Provides a unified interface for assigning the ``fold`` attribute to
105
+ datetimes both before and after the implementation of PEP-495.
106
+
107
+ :param fold:
108
+ The value for the ``fold`` attribute in the returned datetime. This
109
+ should be either 0 or 1.
110
+
111
+ :return:
112
+ Returns an object for which ``getattr(dt, 'fold', 0)`` returns
113
+ ``fold`` for all versions of Python. In versions prior to
114
+ Python 3.6, this is a ``_DatetimeWithFold`` object, which is a
115
+ subclass of :py:class:`datetime.datetime` with the ``fold``
116
+ attribute added, if ``fold`` is 1.
117
+
118
+ .. versionadded:: 2.6.0
119
+ """
120
+ if getattr(dt, 'fold', 0) == fold:
121
+ return dt
122
+
123
+ args = dt.timetuple()[:6]
124
+ args += (dt.microsecond, dt.tzinfo)
125
+
126
+ if fold:
127
+ return _DatetimeWithFold(*args)
128
+ else:
129
+ return datetime(*args)
130
+
131
+
132
+ def _validate_fromutc_inputs(f):
133
+ """
134
+ The CPython version of ``fromutc`` checks that the input is a ``datetime``
135
+ object and that ``self`` is attached as its ``tzinfo``.
136
+ """
137
+ @wraps(f)
138
+ def fromutc(self, dt):
139
+ if not isinstance(dt, datetime):
140
+ raise TypeError("fromutc() requires a datetime argument")
141
+ if dt.tzinfo is not self:
142
+ raise ValueError("dt.tzinfo is not self")
143
+
144
+ return f(self, dt)
145
+
146
+ return fromutc
147
+
148
+
149
+ class _tzinfo(tzinfo):
150
+ """
151
+ Base class for all ``dateutil`` ``tzinfo`` objects.
152
+ """
153
+
154
+ def is_ambiguous(self, dt):
155
+ """
156
+ Whether or not the "wall time" of a given datetime is ambiguous in this
157
+ zone.
158
+
159
+ :param dt:
160
+ A :py:class:`datetime.datetime`, naive or time zone aware.
161
+
162
+
163
+ :return:
164
+ Returns ``True`` if ambiguous, ``False`` otherwise.
165
+
166
+ .. versionadded:: 2.6.0
167
+ """
168
+
169
+ dt = dt.replace(tzinfo=self)
170
+
171
+ wall_0 = enfold(dt, fold=0)
172
+ wall_1 = enfold(dt, fold=1)
173
+
174
+ same_offset = wall_0.utcoffset() == wall_1.utcoffset()
175
+ same_dt = wall_0.replace(tzinfo=None) == wall_1.replace(tzinfo=None)
176
+
177
+ return same_dt and not same_offset
178
+
179
+ def _fold_status(self, dt_utc, dt_wall):
180
+ """
181
+ Determine the fold status of a "wall" datetime, given a representation
182
+ of the same datetime as a (naive) UTC datetime. This is calculated based
183
+ on the assumption that ``dt.utcoffset() - dt.dst()`` is constant for all
184
+ datetimes, and that this offset is the actual number of hours separating
185
+ ``dt_utc`` and ``dt_wall``.
186
+
187
+ :param dt_utc:
188
+ Representation of the datetime as UTC
189
+
190
+ :param dt_wall:
191
+ Representation of the datetime as "wall time". This parameter must
192
+ either have a `fold` attribute or have a fold-naive
193
+ :class:`datetime.tzinfo` attached, otherwise the calculation may
194
+ fail.
195
+ """
196
+ if self.is_ambiguous(dt_wall):
197
+ delta_wall = dt_wall - dt_utc
198
+ _fold = int(delta_wall == (dt_utc.utcoffset() - dt_utc.dst()))
199
+ else:
200
+ _fold = 0
201
+
202
+ return _fold
203
+
204
+ def _fold(self, dt):
205
+ return getattr(dt, 'fold', 0)
206
+
207
+ def _fromutc(self, dt):
208
+ """
209
+ Given a timezone-aware datetime in a given timezone, calculates a
210
+ timezone-aware datetime in a new timezone.
211
+
212
+ Since this is the one time that we *know* we have an unambiguous
213
+ datetime object, we take this opportunity to determine whether the
214
+ datetime is ambiguous and in a "fold" state (e.g. if it's the first
215
+ occurrence, chronologically, of the ambiguous datetime).
216
+
217
+ :param dt:
218
+ A timezone-aware :class:`datetime.datetime` object.
219
+ """
220
+
221
+ # Re-implement the algorithm from Python's datetime.py
222
+ dtoff = dt.utcoffset()
223
+ if dtoff is None:
224
+ raise ValueError("fromutc() requires a non-None utcoffset() "
225
+ "result")
226
+
227
+ # The original datetime.py code assumes that `dst()` defaults to
228
+ # zero during ambiguous times. PEP 495 inverts this presumption, so
229
+ # for pre-PEP 495 versions of python, we need to tweak the algorithm.
230
+ dtdst = dt.dst()
231
+ if dtdst is None:
232
+ raise ValueError("fromutc() requires a non-None dst() result")
233
+ delta = dtoff - dtdst
234
+
235
+ dt += delta
236
+ # Set fold=1 so we can default to being in the fold for
237
+ # ambiguous dates.
238
+ dtdst = enfold(dt, fold=1).dst()
239
+ if dtdst is None:
240
+ raise ValueError("fromutc(): dt.dst gave inconsistent "
241
+ "results; cannot convert")
242
+ return dt + dtdst
243
+
244
+ @_validate_fromutc_inputs
245
+ def fromutc(self, dt):
246
+ """
247
+ Given a timezone-aware datetime in a given timezone, calculates a
248
+ timezone-aware datetime in a new timezone.
249
+
250
+ Since this is the one time that we *know* we have an unambiguous
251
+ datetime object, we take this opportunity to determine whether the
252
+ datetime is ambiguous and in a "fold" state (e.g. if it's the first
253
+ occurrence, chronologically, of the ambiguous datetime).
254
+
255
+ :param dt:
256
+ A timezone-aware :class:`datetime.datetime` object.
257
+ """
258
+ dt_wall = self._fromutc(dt)
259
+
260
+ # Calculate the fold status given the two datetimes.
261
+ _fold = self._fold_status(dt, dt_wall)
262
+
263
+ # Set the default fold value for ambiguous dates
264
+ return enfold(dt_wall, fold=_fold)
265
+
266
+
267
+ class tzrangebase(_tzinfo):
268
+ """
269
+ This is an abstract base class for time zones represented by an annual
270
+ transition into and out of DST. Child classes should implement the following
271
+ methods:
272
+
273
+ * ``__init__(self, *args, **kwargs)``
274
+ * ``transitions(self, year)`` - this is expected to return a tuple of
275
+ datetimes representing the DST on and off transitions in standard
276
+ time.
277
+
278
+ A fully initialized ``tzrangebase`` subclass should also provide the
279
+ following attributes:
280
+ * ``hasdst``: Boolean whether or not the zone uses DST.
281
+ * ``_dst_offset`` / ``_std_offset``: :class:`datetime.timedelta` objects
282
+ representing the respective UTC offsets.
283
+ * ``_dst_abbr`` / ``_std_abbr``: Strings representing the timezone short
284
+ abbreviations in DST and STD, respectively.
285
+ * ``_hasdst``: Whether or not the zone has DST.
286
+
287
+ .. versionadded:: 2.6.0
288
+ """
289
+ def __init__(self):
290
+ raise NotImplementedError('tzrangebase is an abstract base class')
291
+
292
+ def utcoffset(self, dt):
293
+ isdst = self._isdst(dt)
294
+
295
+ if isdst is None:
296
+ return None
297
+ elif isdst:
298
+ return self._dst_offset
299
+ else:
300
+ return self._std_offset
301
+
302
+ def dst(self, dt):
303
+ isdst = self._isdst(dt)
304
+
305
+ if isdst is None:
306
+ return None
307
+ elif isdst:
308
+ return self._dst_base_offset
309
+ else:
310
+ return ZERO
311
+
312
+ @tzname_in_python2
313
+ def tzname(self, dt):
314
+ if self._isdst(dt):
315
+ return self._dst_abbr
316
+ else:
317
+ return self._std_abbr
318
+
319
+ def fromutc(self, dt):
320
+ """ Given a datetime in UTC, return local time """
321
+ if not isinstance(dt, datetime):
322
+ raise TypeError("fromutc() requires a datetime argument")
323
+
324
+ if dt.tzinfo is not self:
325
+ raise ValueError("dt.tzinfo is not self")
326
+
327
+ # Get transitions - if there are none, fixed offset
328
+ transitions = self.transitions(dt.year)
329
+ if transitions is None:
330
+ return dt + self.utcoffset(dt)
331
+
332
+ # Get the transition times in UTC
333
+ dston, dstoff = transitions
334
+
335
+ dston -= self._std_offset
336
+ dstoff -= self._std_offset
337
+
338
+ utc_transitions = (dston, dstoff)
339
+ dt_utc = dt.replace(tzinfo=None)
340
+
341
+ isdst = self._naive_isdst(dt_utc, utc_transitions)
342
+
343
+ if isdst:
344
+ dt_wall = dt + self._dst_offset
345
+ else:
346
+ dt_wall = dt + self._std_offset
347
+
348
+ _fold = int(not isdst and self.is_ambiguous(dt_wall))
349
+
350
+ return enfold(dt_wall, fold=_fold)
351
+
352
+ def is_ambiguous(self, dt):
353
+ """
354
+ Whether or not the "wall time" of a given datetime is ambiguous in this
355
+ zone.
356
+
357
+ :param dt:
358
+ A :py:class:`datetime.datetime`, naive or time zone aware.
359
+
360
+
361
+ :return:
362
+ Returns ``True`` if ambiguous, ``False`` otherwise.
363
+
364
+ .. versionadded:: 2.6.0
365
+ """
366
+ if not self.hasdst:
367
+ return False
368
+
369
+ start, end = self.transitions(dt.year)
370
+
371
+ dt = dt.replace(tzinfo=None)
372
+ return (end <= dt < end + self._dst_base_offset)
373
+
374
+ def _isdst(self, dt):
375
+ if not self.hasdst:
376
+ return False
377
+ elif dt is None:
378
+ return None
379
+
380
+ transitions = self.transitions(dt.year)
381
+
382
+ if transitions is None:
383
+ return False
384
+
385
+ dt = dt.replace(tzinfo=None)
386
+
387
+ isdst = self._naive_isdst(dt, transitions)
388
+
389
+ # Handle ambiguous dates
390
+ if not isdst and self.is_ambiguous(dt):
391
+ return not self._fold(dt)
392
+ else:
393
+ return isdst
394
+
395
+ def _naive_isdst(self, dt, transitions):
396
+ dston, dstoff = transitions
397
+
398
+ dt = dt.replace(tzinfo=None)
399
+
400
+ if dston < dstoff:
401
+ isdst = dston <= dt < dstoff
402
+ else:
403
+ isdst = not dstoff <= dt < dston
404
+
405
+ return isdst
406
+
407
+ @property
408
+ def _dst_base_offset(self):
409
+ return self._dst_offset - self._std_offset
410
+
411
+ __hash__ = None
412
+
413
+ def __ne__(self, other):
414
+ return not (self == other)
415
+
416
+ def __repr__(self):
417
+ return "%s(...)" % self.__class__.__name__
418
+
419
+ __reduce__ = object.__reduce__
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/_factories.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import timedelta
2
+ import weakref
3
+ from collections import OrderedDict
4
+
5
+ from six.moves import _thread
6
+
7
+
8
+ class _TzSingleton(type):
9
+ def __init__(cls, *args, **kwargs):
10
+ cls.__instance = None
11
+ super(_TzSingleton, cls).__init__(*args, **kwargs)
12
+
13
+ def __call__(cls):
14
+ if cls.__instance is None:
15
+ cls.__instance = super(_TzSingleton, cls).__call__()
16
+ return cls.__instance
17
+
18
+
19
+ class _TzFactory(type):
20
+ def instance(cls, *args, **kwargs):
21
+ """Alternate constructor that returns a fresh instance"""
22
+ return type.__call__(cls, *args, **kwargs)
23
+
24
+
25
+ class _TzOffsetFactory(_TzFactory):
26
+ def __init__(cls, *args, **kwargs):
27
+ cls.__instances = weakref.WeakValueDictionary()
28
+ cls.__strong_cache = OrderedDict()
29
+ cls.__strong_cache_size = 8
30
+
31
+ cls._cache_lock = _thread.allocate_lock()
32
+
33
+ def __call__(cls, name, offset):
34
+ if isinstance(offset, timedelta):
35
+ key = (name, offset.total_seconds())
36
+ else:
37
+ key = (name, offset)
38
+
39
+ instance = cls.__instances.get(key, None)
40
+ if instance is None:
41
+ instance = cls.__instances.setdefault(key,
42
+ cls.instance(name, offset))
43
+
44
+ # This lock may not be necessary in Python 3. See GH issue #901
45
+ with cls._cache_lock:
46
+ cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)
47
+
48
+ # Remove an item if the strong cache is overpopulated
49
+ if len(cls.__strong_cache) > cls.__strong_cache_size:
50
+ cls.__strong_cache.popitem(last=False)
51
+
52
+ return instance
53
+
54
+
55
+ class _TzStrFactory(_TzFactory):
56
+ def __init__(cls, *args, **kwargs):
57
+ cls.__instances = weakref.WeakValueDictionary()
58
+ cls.__strong_cache = OrderedDict()
59
+ cls.__strong_cache_size = 8
60
+
61
+ cls.__cache_lock = _thread.allocate_lock()
62
+
63
+ def __call__(cls, s, posix_offset=False):
64
+ key = (s, posix_offset)
65
+ instance = cls.__instances.get(key, None)
66
+
67
+ if instance is None:
68
+ instance = cls.__instances.setdefault(key,
69
+ cls.instance(s, posix_offset))
70
+
71
+ # This lock may not be necessary in Python 3. See GH issue #901
72
+ with cls.__cache_lock:
73
+ cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)
74
+
75
+ # Remove an item if the strong cache is overpopulated
76
+ if len(cls.__strong_cache) > cls.__strong_cache_size:
77
+ cls.__strong_cache.popitem(last=False)
78
+
79
+ return instance
80
+
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/tz.py ADDED
@@ -0,0 +1,1849 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ This module offers timezone implementations subclassing the abstract
4
+ :py:class:`datetime.tzinfo` type. There are classes to handle tzfile format
5
+ files (usually are in :file:`/etc/localtime`, :file:`/usr/share/zoneinfo`,
6
+ etc), TZ environment string (in all known formats), given ranges (with help
7
+ from relative deltas), local machine timezone, fixed offset timezone, and UTC
8
+ timezone.
9
+ """
10
+ import datetime
11
+ import struct
12
+ import time
13
+ import sys
14
+ import os
15
+ import bisect
16
+ import weakref
17
+ from collections import OrderedDict
18
+
19
+ import six
20
+ from six import string_types
21
+ from six.moves import _thread
22
+ from ._common import tzname_in_python2, _tzinfo
23
+ from ._common import tzrangebase, enfold
24
+ from ._common import _validate_fromutc_inputs
25
+
26
+ from ._factories import _TzSingleton, _TzOffsetFactory
27
+ from ._factories import _TzStrFactory
28
+ try:
29
+ from .win import tzwin, tzwinlocal
30
+ except ImportError:
31
+ tzwin = tzwinlocal = None
32
+
33
+ # For warning about rounding tzinfo
34
+ from warnings import warn
35
+
36
+ ZERO = datetime.timedelta(0)
37
+ EPOCH = datetime.datetime(1970, 1, 1, 0, 0)
38
+ EPOCHORDINAL = EPOCH.toordinal()
39
+
40
+
41
+ @six.add_metaclass(_TzSingleton)
42
+ class tzutc(datetime.tzinfo):
43
+ """
44
+ This is a tzinfo object that represents the UTC time zone.
45
+
46
+ **Examples:**
47
+
48
+ .. doctest::
49
+
50
+ >>> from datetime import *
51
+ >>> from dateutil.tz import *
52
+
53
+ >>> datetime.now()
54
+ datetime.datetime(2003, 9, 27, 9, 40, 1, 521290)
55
+
56
+ >>> datetime.now(tzutc())
57
+ datetime.datetime(2003, 9, 27, 12, 40, 12, 156379, tzinfo=tzutc())
58
+
59
+ >>> datetime.now(tzutc()).tzname()
60
+ 'UTC'
61
+
62
+ .. versionchanged:: 2.7.0
63
+ ``tzutc()`` is now a singleton, so the result of ``tzutc()`` will
64
+ always return the same object.
65
+
66
+ .. doctest::
67
+
68
+ >>> from dateutil.tz import tzutc, UTC
69
+ >>> tzutc() is tzutc()
70
+ True
71
+ >>> tzutc() is UTC
72
+ True
73
+ """
74
+ def utcoffset(self, dt):
75
+ return ZERO
76
+
77
+ def dst(self, dt):
78
+ return ZERO
79
+
80
+ @tzname_in_python2
81
+ def tzname(self, dt):
82
+ return "UTC"
83
+
84
+ def is_ambiguous(self, dt):
85
+ """
86
+ Whether or not the "wall time" of a given datetime is ambiguous in this
87
+ zone.
88
+
89
+ :param dt:
90
+ A :py:class:`datetime.datetime`, naive or time zone aware.
91
+
92
+
93
+ :return:
94
+ Returns ``True`` if ambiguous, ``False`` otherwise.
95
+
96
+ .. versionadded:: 2.6.0
97
+ """
98
+ return False
99
+
100
+ @_validate_fromutc_inputs
101
+ def fromutc(self, dt):
102
+ """
103
+ Fast track version of fromutc() returns the original ``dt`` object for
104
+ any valid :py:class:`datetime.datetime` object.
105
+ """
106
+ return dt
107
+
108
+ def __eq__(self, other):
109
+ if not isinstance(other, (tzutc, tzoffset)):
110
+ return NotImplemented
111
+
112
+ return (isinstance(other, tzutc) or
113
+ (isinstance(other, tzoffset) and other._offset == ZERO))
114
+
115
+ __hash__ = None
116
+
117
+ def __ne__(self, other):
118
+ return not (self == other)
119
+
120
+ def __repr__(self):
121
+ return "%s()" % self.__class__.__name__
122
+
123
+ __reduce__ = object.__reduce__
124
+
125
+
126
+ #: Convenience constant providing a :class:`tzutc()` instance
127
+ #:
128
+ #: .. versionadded:: 2.7.0
129
+ UTC = tzutc()
130
+
131
+
132
+ @six.add_metaclass(_TzOffsetFactory)
133
+ class tzoffset(datetime.tzinfo):
134
+ """
135
+ A simple class for representing a fixed offset from UTC.
136
+
137
+ :param name:
138
+ The timezone name, to be returned when ``tzname()`` is called.
139
+ :param offset:
140
+ The time zone offset in seconds, or (since version 2.6.0, represented
141
+ as a :py:class:`datetime.timedelta` object).
142
+ """
143
+ def __init__(self, name, offset):
144
+ self._name = name
145
+
146
+ try:
147
+ # Allow a timedelta
148
+ offset = offset.total_seconds()
149
+ except (TypeError, AttributeError):
150
+ pass
151
+
152
+ self._offset = datetime.timedelta(seconds=_get_supported_offset(offset))
153
+
154
+ def utcoffset(self, dt):
155
+ return self._offset
156
+
157
+ def dst(self, dt):
158
+ return ZERO
159
+
160
+ @tzname_in_python2
161
+ def tzname(self, dt):
162
+ return self._name
163
+
164
+ @_validate_fromutc_inputs
165
+ def fromutc(self, dt):
166
+ return dt + self._offset
167
+
168
+ def is_ambiguous(self, dt):
169
+ """
170
+ Whether or not the "wall time" of a given datetime is ambiguous in this
171
+ zone.
172
+
173
+ :param dt:
174
+ A :py:class:`datetime.datetime`, naive or time zone aware.
175
+ :return:
176
+ Returns ``True`` if ambiguous, ``False`` otherwise.
177
+
178
+ .. versionadded:: 2.6.0
179
+ """
180
+ return False
181
+
182
+ def __eq__(self, other):
183
+ if not isinstance(other, tzoffset):
184
+ return NotImplemented
185
+
186
+ return self._offset == other._offset
187
+
188
+ __hash__ = None
189
+
190
+ def __ne__(self, other):
191
+ return not (self == other)
192
+
193
+ def __repr__(self):
194
+ return "%s(%s, %s)" % (self.__class__.__name__,
195
+ repr(self._name),
196
+ int(self._offset.total_seconds()))
197
+
198
+ __reduce__ = object.__reduce__
199
+
200
+
201
+ class tzlocal(_tzinfo):
202
+ """
203
+ A :class:`tzinfo` subclass built around the ``time`` timezone functions.
204
+ """
205
+ def __init__(self):
206
+ super(tzlocal, self).__init__()
207
+
208
+ self._std_offset = datetime.timedelta(seconds=-time.timezone)
209
+ if time.daylight:
210
+ self._dst_offset = datetime.timedelta(seconds=-time.altzone)
211
+ else:
212
+ self._dst_offset = self._std_offset
213
+
214
+ self._dst_saved = self._dst_offset - self._std_offset
215
+ self._hasdst = bool(self._dst_saved)
216
+ self._tznames = tuple(time.tzname)
217
+
218
+ def utcoffset(self, dt):
219
+ if dt is None and self._hasdst:
220
+ return None
221
+
222
+ if self._isdst(dt):
223
+ return self._dst_offset
224
+ else:
225
+ return self._std_offset
226
+
227
+ def dst(self, dt):
228
+ if dt is None and self._hasdst:
229
+ return None
230
+
231
+ if self._isdst(dt):
232
+ return self._dst_offset - self._std_offset
233
+ else:
234
+ return ZERO
235
+
236
+ @tzname_in_python2
237
+ def tzname(self, dt):
238
+ return self._tznames[self._isdst(dt)]
239
+
240
+ def is_ambiguous(self, dt):
241
+ """
242
+ Whether or not the "wall time" of a given datetime is ambiguous in this
243
+ zone.
244
+
245
+ :param dt:
246
+ A :py:class:`datetime.datetime`, naive or time zone aware.
247
+
248
+
249
+ :return:
250
+ Returns ``True`` if ambiguous, ``False`` otherwise.
251
+
252
+ .. versionadded:: 2.6.0
253
+ """
254
+ naive_dst = self._naive_is_dst(dt)
255
+ return (not naive_dst and
256
+ (naive_dst != self._naive_is_dst(dt - self._dst_saved)))
257
+
258
+ def _naive_is_dst(self, dt):
259
+ timestamp = _datetime_to_timestamp(dt)
260
+ return time.localtime(timestamp + time.timezone).tm_isdst
261
+
262
+ def _isdst(self, dt, fold_naive=True):
263
+ # We can't use mktime here. It is unstable when deciding if
264
+ # the hour near to a change is DST or not.
265
+ #
266
+ # timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour,
267
+ # dt.minute, dt.second, dt.weekday(), 0, -1))
268
+ # return time.localtime(timestamp).tm_isdst
269
+ #
270
+ # The code above yields the following result:
271
+ #
272
+ # >>> import tz, datetime
273
+ # >>> t = tz.tzlocal()
274
+ # >>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname()
275
+ # 'BRDT'
276
+ # >>> datetime.datetime(2003,2,16,0,tzinfo=t).tzname()
277
+ # 'BRST'
278
+ # >>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname()
279
+ # 'BRST'
280
+ # >>> datetime.datetime(2003,2,15,22,tzinfo=t).tzname()
281
+ # 'BRDT'
282
+ # >>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname()
283
+ # 'BRDT'
284
+ #
285
+ # Here is a more stable implementation:
286
+ #
287
+ if not self._hasdst:
288
+ return False
289
+
290
+ # Check for ambiguous times:
291
+ dstval = self._naive_is_dst(dt)
292
+ fold = getattr(dt, 'fold', None)
293
+
294
+ if self.is_ambiguous(dt):
295
+ if fold is not None:
296
+ return not self._fold(dt)
297
+ else:
298
+ return True
299
+
300
+ return dstval
301
+
302
+ def __eq__(self, other):
303
+ if isinstance(other, tzlocal):
304
+ return (self._std_offset == other._std_offset and
305
+ self._dst_offset == other._dst_offset)
306
+ elif isinstance(other, tzutc):
307
+ return (not self._hasdst and
308
+ self._tznames[0] in {'UTC', 'GMT'} and
309
+ self._std_offset == ZERO)
310
+ elif isinstance(other, tzoffset):
311
+ return (not self._hasdst and
312
+ self._tznames[0] == other._name and
313
+ self._std_offset == other._offset)
314
+ else:
315
+ return NotImplemented
316
+
317
+ __hash__ = None
318
+
319
+ def __ne__(self, other):
320
+ return not (self == other)
321
+
322
+ def __repr__(self):
323
+ return "%s()" % self.__class__.__name__
324
+
325
+ __reduce__ = object.__reduce__
326
+
327
+
328
+ class _ttinfo(object):
329
+ __slots__ = ["offset", "delta", "isdst", "abbr",
330
+ "isstd", "isgmt", "dstoffset"]
331
+
332
+ def __init__(self):
333
+ for attr in self.__slots__:
334
+ setattr(self, attr, None)
335
+
336
+ def __repr__(self):
337
+ l = []
338
+ for attr in self.__slots__:
339
+ value = getattr(self, attr)
340
+ if value is not None:
341
+ l.append("%s=%s" % (attr, repr(value)))
342
+ return "%s(%s)" % (self.__class__.__name__, ", ".join(l))
343
+
344
+ def __eq__(self, other):
345
+ if not isinstance(other, _ttinfo):
346
+ return NotImplemented
347
+
348
+ return (self.offset == other.offset and
349
+ self.delta == other.delta and
350
+ self.isdst == other.isdst and
351
+ self.abbr == other.abbr and
352
+ self.isstd == other.isstd and
353
+ self.isgmt == other.isgmt and
354
+ self.dstoffset == other.dstoffset)
355
+
356
+ __hash__ = None
357
+
358
+ def __ne__(self, other):
359
+ return not (self == other)
360
+
361
+ def __getstate__(self):
362
+ state = {}
363
+ for name in self.__slots__:
364
+ state[name] = getattr(self, name, None)
365
+ return state
366
+
367
+ def __setstate__(self, state):
368
+ for name in self.__slots__:
369
+ if name in state:
370
+ setattr(self, name, state[name])
371
+
372
+
373
+ class _tzfile(object):
374
+ """
375
+ Lightweight class for holding the relevant transition and time zone
376
+ information read from binary tzfiles.
377
+ """
378
+ attrs = ['trans_list', 'trans_list_utc', 'trans_idx', 'ttinfo_list',
379
+ 'ttinfo_std', 'ttinfo_dst', 'ttinfo_before', 'ttinfo_first']
380
+
381
+ def __init__(self, **kwargs):
382
+ for attr in self.attrs:
383
+ setattr(self, attr, kwargs.get(attr, None))
384
+
385
+
386
+ class tzfile(_tzinfo):
387
+ """
388
+ This is a ``tzinfo`` subclass that allows one to use the ``tzfile(5)``
389
+ format timezone files to extract current and historical zone information.
390
+
391
+ :param fileobj:
392
+ This can be an opened file stream or a file name that the time zone
393
+ information can be read from.
394
+
395
+ :param filename:
396
+ This is an optional parameter specifying the source of the time zone
397
+ information in the event that ``fileobj`` is a file object. If omitted
398
+ and ``fileobj`` is a file stream, this parameter will be set either to
399
+ ``fileobj``'s ``name`` attribute or to ``repr(fileobj)``.
400
+
401
+ See `Sources for Time Zone and Daylight Saving Time Data
402
+ <https://data.iana.org/time-zones/tz-link.html>`_ for more information.
403
+ Time zone files can be compiled from the `IANA Time Zone database files
404
+ <https://www.iana.org/time-zones>`_ with the `zic time zone compiler
405
+ <https://www.freebsd.org/cgi/man.cgi?query=zic&sektion=8>`_
406
+
407
+ .. note::
408
+
409
+ Only construct a ``tzfile`` directly if you have a specific timezone
410
+ file on disk that you want to read into a Python ``tzinfo`` object.
411
+ If you want to get a ``tzfile`` representing a specific IANA zone,
412
+ (e.g. ``'America/New_York'``), you should call
413
+ :func:`dateutil.tz.gettz` with the zone identifier.
414
+
415
+
416
+ **Examples:**
417
+
418
+ Using the US Eastern time zone as an example, we can see that a ``tzfile``
419
+ provides time zone information for the standard Daylight Saving offsets:
420
+
421
+ .. testsetup:: tzfile
422
+
423
+ from dateutil.tz import gettz
424
+ from datetime import datetime
425
+
426
+ .. doctest:: tzfile
427
+
428
+ >>> NYC = gettz('America/New_York')
429
+ >>> NYC
430
+ tzfile('/usr/share/zoneinfo/America/New_York')
431
+
432
+ >>> print(datetime(2016, 1, 3, tzinfo=NYC)) # EST
433
+ 2016-01-03 00:00:00-05:00
434
+
435
+ >>> print(datetime(2016, 7, 7, tzinfo=NYC)) # EDT
436
+ 2016-07-07 00:00:00-04:00
437
+
438
+
439
+ The ``tzfile`` structure contains a fully history of the time zone,
440
+ so historical dates will also have the right offsets. For example, before
441
+ the adoption of the UTC standards, New York used local solar mean time:
442
+
443
+ .. doctest:: tzfile
444
+
445
+ >>> print(datetime(1901, 4, 12, tzinfo=NYC)) # LMT
446
+ 1901-04-12 00:00:00-04:56
447
+
448
+ And during World War II, New York was on "Eastern War Time", which was a
449
+ state of permanent daylight saving time:
450
+
451
+ .. doctest:: tzfile
452
+
453
+ >>> print(datetime(1944, 2, 7, tzinfo=NYC)) # EWT
454
+ 1944-02-07 00:00:00-04:00
455
+
456
+ """
457
+
458
+ def __init__(self, fileobj, filename=None):
459
+ super(tzfile, self).__init__()
460
+
461
+ file_opened_here = False
462
+ if isinstance(fileobj, string_types):
463
+ self._filename = fileobj
464
+ fileobj = open(fileobj, 'rb')
465
+ file_opened_here = True
466
+ elif filename is not None:
467
+ self._filename = filename
468
+ elif hasattr(fileobj, "name"):
469
+ self._filename = fileobj.name
470
+ else:
471
+ self._filename = repr(fileobj)
472
+
473
+ if fileobj is not None:
474
+ if not file_opened_here:
475
+ fileobj = _nullcontext(fileobj)
476
+
477
+ with fileobj as file_stream:
478
+ tzobj = self._read_tzfile(file_stream)
479
+
480
+ self._set_tzdata(tzobj)
481
+
482
+ def _set_tzdata(self, tzobj):
483
+ """ Set the time zone data of this object from a _tzfile object """
484
+ # Copy the relevant attributes over as private attributes
485
+ for attr in _tzfile.attrs:
486
+ setattr(self, '_' + attr, getattr(tzobj, attr))
487
+
488
+ def _read_tzfile(self, fileobj):
489
+ out = _tzfile()
490
+
491
+ # From tzfile(5):
492
+ #
493
+ # The time zone information files used by tzset(3)
494
+ # begin with the magic characters "TZif" to identify
495
+ # them as time zone information files, followed by
496
+ # sixteen bytes reserved for future use, followed by
497
+ # six four-byte values of type long, written in a
498
+ # ``standard'' byte order (the high-order byte
499
+ # of the value is written first).
500
+ if fileobj.read(4).decode() != "TZif":
501
+ raise ValueError("magic not found")
502
+
503
+ fileobj.read(16)
504
+
505
+ (
506
+ # The number of UTC/local indicators stored in the file.
507
+ ttisgmtcnt,
508
+
509
+ # The number of standard/wall indicators stored in the file.
510
+ ttisstdcnt,
511
+
512
+ # The number of leap seconds for which data is
513
+ # stored in the file.
514
+ leapcnt,
515
+
516
+ # The number of "transition times" for which data
517
+ # is stored in the file.
518
+ timecnt,
519
+
520
+ # The number of "local time types" for which data
521
+ # is stored in the file (must not be zero).
522
+ typecnt,
523
+
524
+ # The number of characters of "time zone
525
+ # abbreviation strings" stored in the file.
526
+ charcnt,
527
+
528
+ ) = struct.unpack(">6l", fileobj.read(24))
529
+
530
+ # The above header is followed by tzh_timecnt four-byte
531
+ # values of type long, sorted in ascending order.
532
+ # These values are written in ``standard'' byte order.
533
+ # Each is used as a transition time (as returned by
534
+ # time(2)) at which the rules for computing local time
535
+ # change.
536
+
537
+ if timecnt:
538
+ out.trans_list_utc = list(struct.unpack(">%dl" % timecnt,
539
+ fileobj.read(timecnt*4)))
540
+ else:
541
+ out.trans_list_utc = []
542
+
543
+ # Next come tzh_timecnt one-byte values of type unsigned
544
+ # char; each one tells which of the different types of
545
+ # ``local time'' types described in the file is associated
546
+ # with the same-indexed transition time. These values
547
+ # serve as indices into an array of ttinfo structures that
548
+ # appears next in the file.
549
+
550
+ if timecnt:
551
+ out.trans_idx = struct.unpack(">%dB" % timecnt,
552
+ fileobj.read(timecnt))
553
+ else:
554
+ out.trans_idx = []
555
+
556
+ # Each ttinfo structure is written as a four-byte value
557
+ # for tt_gmtoff of type long, in a standard byte
558
+ # order, followed by a one-byte value for tt_isdst
559
+ # and a one-byte value for tt_abbrind. In each
560
+ # structure, tt_gmtoff gives the number of
561
+ # seconds to be added to UTC, tt_isdst tells whether
562
+ # tm_isdst should be set by localtime(3), and
563
+ # tt_abbrind serves as an index into the array of
564
+ # time zone abbreviation characters that follow the
565
+ # ttinfo structure(s) in the file.
566
+
567
+ ttinfo = []
568
+
569
+ for i in range(typecnt):
570
+ ttinfo.append(struct.unpack(">lbb", fileobj.read(6)))
571
+
572
+ abbr = fileobj.read(charcnt).decode()
573
+
574
+ # Then there are tzh_leapcnt pairs of four-byte
575
+ # values, written in standard byte order; the
576
+ # first value of each pair gives the time (as
577
+ # returned by time(2)) at which a leap second
578
+ # occurs; the second gives the total number of
579
+ # leap seconds to be applied after the given time.
580
+ # The pairs of values are sorted in ascending order
581
+ # by time.
582
+
583
+ # Not used, for now (but seek for correct file position)
584
+ if leapcnt:
585
+ fileobj.seek(leapcnt * 8, os.SEEK_CUR)
586
+
587
+ # Then there are tzh_ttisstdcnt standard/wall
588
+ # indicators, each stored as a one-byte value;
589
+ # they tell whether the transition times associated
590
+ # with local time types were specified as standard
591
+ # time or wall clock time, and are used when
592
+ # a time zone file is used in handling POSIX-style
593
+ # time zone environment variables.
594
+
595
+ if ttisstdcnt:
596
+ isstd = struct.unpack(">%db" % ttisstdcnt,
597
+ fileobj.read(ttisstdcnt))
598
+
599
+ # Finally, there are tzh_ttisgmtcnt UTC/local
600
+ # indicators, each stored as a one-byte value;
601
+ # they tell whether the transition times associated
602
+ # with local time types were specified as UTC or
603
+ # local time, and are used when a time zone file
604
+ # is used in handling POSIX-style time zone envi-
605
+ # ronment variables.
606
+
607
+ if ttisgmtcnt:
608
+ isgmt = struct.unpack(">%db" % ttisgmtcnt,
609
+ fileobj.read(ttisgmtcnt))
610
+
611
+ # Build ttinfo list
612
+ out.ttinfo_list = []
613
+ for i in range(typecnt):
614
+ gmtoff, isdst, abbrind = ttinfo[i]
615
+ gmtoff = _get_supported_offset(gmtoff)
616
+ tti = _ttinfo()
617
+ tti.offset = gmtoff
618
+ tti.dstoffset = datetime.timedelta(0)
619
+ tti.delta = datetime.timedelta(seconds=gmtoff)
620
+ tti.isdst = isdst
621
+ tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)]
622
+ tti.isstd = (ttisstdcnt > i and isstd[i] != 0)
623
+ tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0)
624
+ out.ttinfo_list.append(tti)
625
+
626
+ # Replace ttinfo indexes for ttinfo objects.
627
+ out.trans_idx = [out.ttinfo_list[idx] for idx in out.trans_idx]
628
+
629
+ # Set standard, dst, and before ttinfos. before will be
630
+ # used when a given time is before any transitions,
631
+ # and will be set to the first non-dst ttinfo, or to
632
+ # the first dst, if all of them are dst.
633
+ out.ttinfo_std = None
634
+ out.ttinfo_dst = None
635
+ out.ttinfo_before = None
636
+ if out.ttinfo_list:
637
+ if not out.trans_list_utc:
638
+ out.ttinfo_std = out.ttinfo_first = out.ttinfo_list[0]
639
+ else:
640
+ for i in range(timecnt-1, -1, -1):
641
+ tti = out.trans_idx[i]
642
+ if not out.ttinfo_std and not tti.isdst:
643
+ out.ttinfo_std = tti
644
+ elif not out.ttinfo_dst and tti.isdst:
645
+ out.ttinfo_dst = tti
646
+
647
+ if out.ttinfo_std and out.ttinfo_dst:
648
+ break
649
+ else:
650
+ if out.ttinfo_dst and not out.ttinfo_std:
651
+ out.ttinfo_std = out.ttinfo_dst
652
+
653
+ for tti in out.ttinfo_list:
654
+ if not tti.isdst:
655
+ out.ttinfo_before = tti
656
+ break
657
+ else:
658
+ out.ttinfo_before = out.ttinfo_list[0]
659
+
660
+ # Now fix transition times to become relative to wall time.
661
+ #
662
+ # I'm not sure about this. In my tests, the tz source file
663
+ # is setup to wall time, and in the binary file isstd and
664
+ # isgmt are off, so it should be in wall time. OTOH, it's
665
+ # always in gmt time. Let me know if you have comments
666
+ # about this.
667
+ lastdst = None
668
+ lastoffset = None
669
+ lastdstoffset = None
670
+ lastbaseoffset = None
671
+ out.trans_list = []
672
+
673
+ for i, tti in enumerate(out.trans_idx):
674
+ offset = tti.offset
675
+ dstoffset = 0
676
+
677
+ if lastdst is not None:
678
+ if tti.isdst:
679
+ if not lastdst:
680
+ dstoffset = offset - lastoffset
681
+
682
+ if not dstoffset and lastdstoffset:
683
+ dstoffset = lastdstoffset
684
+
685
+ tti.dstoffset = datetime.timedelta(seconds=dstoffset)
686
+ lastdstoffset = dstoffset
687
+
688
+ # If a time zone changes its base offset during a DST transition,
689
+ # then you need to adjust by the previous base offset to get the
690
+ # transition time in local time. Otherwise you use the current
691
+ # base offset. Ideally, I would have some mathematical proof of
692
+ # why this is true, but I haven't really thought about it enough.
693
+ baseoffset = offset - dstoffset
694
+ adjustment = baseoffset
695
+ if (lastbaseoffset is not None and baseoffset != lastbaseoffset
696
+ and tti.isdst != lastdst):
697
+ # The base DST has changed
698
+ adjustment = lastbaseoffset
699
+
700
+ lastdst = tti.isdst
701
+ lastoffset = offset
702
+ lastbaseoffset = baseoffset
703
+
704
+ out.trans_list.append(out.trans_list_utc[i] + adjustment)
705
+
706
+ out.trans_idx = tuple(out.trans_idx)
707
+ out.trans_list = tuple(out.trans_list)
708
+ out.trans_list_utc = tuple(out.trans_list_utc)
709
+
710
+ return out
711
+
712
+ def _find_last_transition(self, dt, in_utc=False):
713
+ # If there's no list, there are no transitions to find
714
+ if not self._trans_list:
715
+ return None
716
+
717
+ timestamp = _datetime_to_timestamp(dt)
718
+
719
+ # Find where the timestamp fits in the transition list - if the
720
+ # timestamp is a transition time, it's part of the "after" period.
721
+ trans_list = self._trans_list_utc if in_utc else self._trans_list
722
+ idx = bisect.bisect_right(trans_list, timestamp)
723
+
724
+ # We want to know when the previous transition was, so subtract off 1
725
+ return idx - 1
726
+
727
+ def _get_ttinfo(self, idx):
728
+ # For no list or after the last transition, default to _ttinfo_std
729
+ if idx is None or (idx + 1) >= len(self._trans_list):
730
+ return self._ttinfo_std
731
+
732
+ # If there is a list and the time is before it, return _ttinfo_before
733
+ if idx < 0:
734
+ return self._ttinfo_before
735
+
736
+ return self._trans_idx[idx]
737
+
738
+ def _find_ttinfo(self, dt):
739
+ idx = self._resolve_ambiguous_time(dt)
740
+
741
+ return self._get_ttinfo(idx)
742
+
743
+ def fromutc(self, dt):
744
+ """
745
+ The ``tzfile`` implementation of :py:func:`datetime.tzinfo.fromutc`.
746
+
747
+ :param dt:
748
+ A :py:class:`datetime.datetime` object.
749
+
750
+ :raises TypeError:
751
+ Raised if ``dt`` is not a :py:class:`datetime.datetime` object.
752
+
753
+ :raises ValueError:
754
+ Raised if this is called with a ``dt`` which does not have this
755
+ ``tzinfo`` attached.
756
+
757
+ :return:
758
+ Returns a :py:class:`datetime.datetime` object representing the
759
+ wall time in ``self``'s time zone.
760
+ """
761
+ # These isinstance checks are in datetime.tzinfo, so we'll preserve
762
+ # them, even if we don't care about duck typing.
763
+ if not isinstance(dt, datetime.datetime):
764
+ raise TypeError("fromutc() requires a datetime argument")
765
+
766
+ if dt.tzinfo is not self:
767
+ raise ValueError("dt.tzinfo is not self")
768
+
769
+ # First treat UTC as wall time and get the transition we're in.
770
+ idx = self._find_last_transition(dt, in_utc=True)
771
+ tti = self._get_ttinfo(idx)
772
+
773
+ dt_out = dt + datetime.timedelta(seconds=tti.offset)
774
+
775
+ fold = self.is_ambiguous(dt_out, idx=idx)
776
+
777
+ return enfold(dt_out, fold=int(fold))
778
+
779
+ def is_ambiguous(self, dt, idx=None):
780
+ """
781
+ Whether or not the "wall time" of a given datetime is ambiguous in this
782
+ zone.
783
+
784
+ :param dt:
785
+ A :py:class:`datetime.datetime`, naive or time zone aware.
786
+
787
+
788
+ :return:
789
+ Returns ``True`` if ambiguous, ``False`` otherwise.
790
+
791
+ .. versionadded:: 2.6.0
792
+ """
793
+ if idx is None:
794
+ idx = self._find_last_transition(dt)
795
+
796
+ # Calculate the difference in offsets from current to previous
797
+ timestamp = _datetime_to_timestamp(dt)
798
+ tti = self._get_ttinfo(idx)
799
+
800
+ if idx is None or idx <= 0:
801
+ return False
802
+
803
+ od = self._get_ttinfo(idx - 1).offset - tti.offset
804
+ tt = self._trans_list[idx] # Transition time
805
+
806
+ return timestamp < tt + od
807
+
808
+ def _resolve_ambiguous_time(self, dt):
809
+ idx = self._find_last_transition(dt)
810
+
811
+ # If we have no transitions, return the index
812
+ _fold = self._fold(dt)
813
+ if idx is None or idx == 0:
814
+ return idx
815
+
816
+ # If it's ambiguous and we're in a fold, shift to a different index.
817
+ idx_offset = int(not _fold and self.is_ambiguous(dt, idx))
818
+
819
+ return idx - idx_offset
820
+
821
+ def utcoffset(self, dt):
822
+ if dt is None:
823
+ return None
824
+
825
+ if not self._ttinfo_std:
826
+ return ZERO
827
+
828
+ return self._find_ttinfo(dt).delta
829
+
830
+ def dst(self, dt):
831
+ if dt is None:
832
+ return None
833
+
834
+ if not self._ttinfo_dst:
835
+ return ZERO
836
+
837
+ tti = self._find_ttinfo(dt)
838
+
839
+ if not tti.isdst:
840
+ return ZERO
841
+
842
+ # The documentation says that utcoffset()-dst() must
843
+ # be constant for every dt.
844
+ return tti.dstoffset
845
+
846
+ @tzname_in_python2
847
+ def tzname(self, dt):
848
+ if not self._ttinfo_std or dt is None:
849
+ return None
850
+ return self._find_ttinfo(dt).abbr
851
+
852
+ def __eq__(self, other):
853
+ if not isinstance(other, tzfile):
854
+ return NotImplemented
855
+ return (self._trans_list == other._trans_list and
856
+ self._trans_idx == other._trans_idx and
857
+ self._ttinfo_list == other._ttinfo_list)
858
+
859
+ __hash__ = None
860
+
861
+ def __ne__(self, other):
862
+ return not (self == other)
863
+
864
+ def __repr__(self):
865
+ return "%s(%s)" % (self.__class__.__name__, repr(self._filename))
866
+
867
+ def __reduce__(self):
868
+ return self.__reduce_ex__(None)
869
+
870
+ def __reduce_ex__(self, protocol):
871
+ return (self.__class__, (None, self._filename), self.__dict__)
872
+
873
+
874
+ class tzrange(tzrangebase):
875
+ """
876
+ The ``tzrange`` object is a time zone specified by a set of offsets and
877
+ abbreviations, equivalent to the way the ``TZ`` variable can be specified
878
+ in POSIX-like systems, but using Python delta objects to specify DST
879
+ start, end and offsets.
880
+
881
+ :param stdabbr:
882
+ The abbreviation for standard time (e.g. ``'EST'``).
883
+
884
+ :param stdoffset:
885
+ An integer or :class:`datetime.timedelta` object or equivalent
886
+ specifying the base offset from UTC.
887
+
888
+ If unspecified, +00:00 is used.
889
+
890
+ :param dstabbr:
891
+ The abbreviation for DST / "Summer" time (e.g. ``'EDT'``).
892
+
893
+ If specified, with no other DST information, DST is assumed to occur
894
+ and the default behavior or ``dstoffset``, ``start`` and ``end`` is
895
+ used. If unspecified and no other DST information is specified, it
896
+ is assumed that this zone has no DST.
897
+
898
+ If this is unspecified and other DST information is *is* specified,
899
+ DST occurs in the zone but the time zone abbreviation is left
900
+ unchanged.
901
+
902
+ :param dstoffset:
903
+ A an integer or :class:`datetime.timedelta` object or equivalent
904
+ specifying the UTC offset during DST. If unspecified and any other DST
905
+ information is specified, it is assumed to be the STD offset +1 hour.
906
+
907
+ :param start:
908
+ A :class:`relativedelta.relativedelta` object or equivalent specifying
909
+ the time and time of year that daylight savings time starts. To
910
+ specify, for example, that DST starts at 2AM on the 2nd Sunday in
911
+ March, pass:
912
+
913
+ ``relativedelta(hours=2, month=3, day=1, weekday=SU(+2))``
914
+
915
+ If unspecified and any other DST information is specified, the default
916
+ value is 2 AM on the first Sunday in April.
917
+
918
+ :param end:
919
+ A :class:`relativedelta.relativedelta` object or equivalent
920
+ representing the time and time of year that daylight savings time
921
+ ends, with the same specification method as in ``start``. One note is
922
+ that this should point to the first time in the *standard* zone, so if
923
+ a transition occurs at 2AM in the DST zone and the clocks are set back
924
+ 1 hour to 1AM, set the ``hours`` parameter to +1.
925
+
926
+
927
+ **Examples:**
928
+
929
+ .. testsetup:: tzrange
930
+
931
+ from dateutil.tz import tzrange, tzstr
932
+
933
+ .. doctest:: tzrange
934
+
935
+ >>> tzstr('EST5EDT') == tzrange("EST", -18000, "EDT")
936
+ True
937
+
938
+ >>> from dateutil.relativedelta import *
939
+ >>> range1 = tzrange("EST", -18000, "EDT")
940
+ >>> range2 = tzrange("EST", -18000, "EDT", -14400,
941
+ ... relativedelta(hours=+2, month=4, day=1,
942
+ ... weekday=SU(+1)),
943
+ ... relativedelta(hours=+1, month=10, day=31,
944
+ ... weekday=SU(-1)))
945
+ >>> tzstr('EST5EDT') == range1 == range2
946
+ True
947
+
948
+ """
949
+ def __init__(self, stdabbr, stdoffset=None,
950
+ dstabbr=None, dstoffset=None,
951
+ start=None, end=None):
952
+
953
+ global relativedelta
954
+ from dateutil import relativedelta
955
+
956
+ self._std_abbr = stdabbr
957
+ self._dst_abbr = dstabbr
958
+
959
+ try:
960
+ stdoffset = stdoffset.total_seconds()
961
+ except (TypeError, AttributeError):
962
+ pass
963
+
964
+ try:
965
+ dstoffset = dstoffset.total_seconds()
966
+ except (TypeError, AttributeError):
967
+ pass
968
+
969
+ if stdoffset is not None:
970
+ self._std_offset = datetime.timedelta(seconds=stdoffset)
971
+ else:
972
+ self._std_offset = ZERO
973
+
974
+ if dstoffset is not None:
975
+ self._dst_offset = datetime.timedelta(seconds=dstoffset)
976
+ elif dstabbr and stdoffset is not None:
977
+ self._dst_offset = self._std_offset + datetime.timedelta(hours=+1)
978
+ else:
979
+ self._dst_offset = ZERO
980
+
981
+ if dstabbr and start is None:
982
+ self._start_delta = relativedelta.relativedelta(
983
+ hours=+2, month=4, day=1, weekday=relativedelta.SU(+1))
984
+ else:
985
+ self._start_delta = start
986
+
987
+ if dstabbr and end is None:
988
+ self._end_delta = relativedelta.relativedelta(
989
+ hours=+1, month=10, day=31, weekday=relativedelta.SU(-1))
990
+ else:
991
+ self._end_delta = end
992
+
993
+ self._dst_base_offset_ = self._dst_offset - self._std_offset
994
+ self.hasdst = bool(self._start_delta)
995
+
996
+ def transitions(self, year):
997
+ """
998
+ For a given year, get the DST on and off transition times, expressed
999
+ always on the standard time side. For zones with no transitions, this
1000
+ function returns ``None``.
1001
+
1002
+ :param year:
1003
+ The year whose transitions you would like to query.
1004
+
1005
+ :return:
1006
+ Returns a :class:`tuple` of :class:`datetime.datetime` objects,
1007
+ ``(dston, dstoff)`` for zones with an annual DST transition, or
1008
+ ``None`` for fixed offset zones.
1009
+ """
1010
+ if not self.hasdst:
1011
+ return None
1012
+
1013
+ base_year = datetime.datetime(year, 1, 1)
1014
+
1015
+ start = base_year + self._start_delta
1016
+ end = base_year + self._end_delta
1017
+
1018
+ return (start, end)
1019
+
1020
+ def __eq__(self, other):
1021
+ if not isinstance(other, tzrange):
1022
+ return NotImplemented
1023
+
1024
+ return (self._std_abbr == other._std_abbr and
1025
+ self._dst_abbr == other._dst_abbr and
1026
+ self._std_offset == other._std_offset and
1027
+ self._dst_offset == other._dst_offset and
1028
+ self._start_delta == other._start_delta and
1029
+ self._end_delta == other._end_delta)
1030
+
1031
+ @property
1032
+ def _dst_base_offset(self):
1033
+ return self._dst_base_offset_
1034
+
1035
+
1036
+ @six.add_metaclass(_TzStrFactory)
1037
+ class tzstr(tzrange):
1038
+ """
1039
+ ``tzstr`` objects are time zone objects specified by a time-zone string as
1040
+ it would be passed to a ``TZ`` variable on POSIX-style systems (see
1041
+ the `GNU C Library: TZ Variable`_ for more details).
1042
+
1043
+ There is one notable exception, which is that POSIX-style time zones use an
1044
+ inverted offset format, so normally ``GMT+3`` would be parsed as an offset
1045
+ 3 hours *behind* GMT. The ``tzstr`` time zone object will parse this as an
1046
+ offset 3 hours *ahead* of GMT. If you would like to maintain the POSIX
1047
+ behavior, pass a ``True`` value to ``posix_offset``.
1048
+
1049
+ The :class:`tzrange` object provides the same functionality, but is
1050
+ specified using :class:`relativedelta.relativedelta` objects. rather than
1051
+ strings.
1052
+
1053
+ :param s:
1054
+ A time zone string in ``TZ`` variable format. This can be a
1055
+ :class:`bytes` (2.x: :class:`str`), :class:`str` (2.x:
1056
+ :class:`unicode`) or a stream emitting unicode characters
1057
+ (e.g. :class:`StringIO`).
1058
+
1059
+ :param posix_offset:
1060
+ Optional. If set to ``True``, interpret strings such as ``GMT+3`` or
1061
+ ``UTC+3`` as being 3 hours *behind* UTC rather than ahead, per the
1062
+ POSIX standard.
1063
+
1064
+ .. caution::
1065
+
1066
+ Prior to version 2.7.0, this function also supported time zones
1067
+ in the format:
1068
+
1069
+ * ``EST5EDT,4,0,6,7200,10,0,26,7200,3600``
1070
+ * ``EST5EDT,4,1,0,7200,10,-1,0,7200,3600``
1071
+
1072
+ This format is non-standard and has been deprecated; this function
1073
+ will raise a :class:`DeprecatedTZFormatWarning` until
1074
+ support is removed in a future version.
1075
+
1076
+ .. _`GNU C Library: TZ Variable`:
1077
+ https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
1078
+ """
1079
+ def __init__(self, s, posix_offset=False):
1080
+ global parser
1081
+ from dateutil.parser import _parser as parser
1082
+
1083
+ self._s = s
1084
+
1085
+ res = parser._parsetz(s)
1086
+ if res is None or res.any_unused_tokens:
1087
+ raise ValueError("unknown string format")
1088
+
1089
+ # Here we break the compatibility with the TZ variable handling.
1090
+ # GMT-3 actually *means* the timezone -3.
1091
+ if res.stdabbr in ("GMT", "UTC") and not posix_offset:
1092
+ res.stdoffset *= -1
1093
+
1094
+ # We must initialize it first, since _delta() needs
1095
+ # _std_offset and _dst_offset set. Use False in start/end
1096
+ # to avoid building it two times.
1097
+ tzrange.__init__(self, res.stdabbr, res.stdoffset,
1098
+ res.dstabbr, res.dstoffset,
1099
+ start=False, end=False)
1100
+
1101
+ if not res.dstabbr:
1102
+ self._start_delta = None
1103
+ self._end_delta = None
1104
+ else:
1105
+ self._start_delta = self._delta(res.start)
1106
+ if self._start_delta:
1107
+ self._end_delta = self._delta(res.end, isend=1)
1108
+
1109
+ self.hasdst = bool(self._start_delta)
1110
+
1111
+ def _delta(self, x, isend=0):
1112
+ from dateutil import relativedelta
1113
+ kwargs = {}
1114
+ if x.month is not None:
1115
+ kwargs["month"] = x.month
1116
+ if x.weekday is not None:
1117
+ kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week)
1118
+ if x.week > 0:
1119
+ kwargs["day"] = 1
1120
+ else:
1121
+ kwargs["day"] = 31
1122
+ elif x.day:
1123
+ kwargs["day"] = x.day
1124
+ elif x.yday is not None:
1125
+ kwargs["yearday"] = x.yday
1126
+ elif x.jyday is not None:
1127
+ kwargs["nlyearday"] = x.jyday
1128
+ if not kwargs:
1129
+ # Default is to start on first sunday of april, and end
1130
+ # on last sunday of october.
1131
+ if not isend:
1132
+ kwargs["month"] = 4
1133
+ kwargs["day"] = 1
1134
+ kwargs["weekday"] = relativedelta.SU(+1)
1135
+ else:
1136
+ kwargs["month"] = 10
1137
+ kwargs["day"] = 31
1138
+ kwargs["weekday"] = relativedelta.SU(-1)
1139
+ if x.time is not None:
1140
+ kwargs["seconds"] = x.time
1141
+ else:
1142
+ # Default is 2AM.
1143
+ kwargs["seconds"] = 7200
1144
+ if isend:
1145
+ # Convert to standard time, to follow the documented way
1146
+ # of working with the extra hour. See the documentation
1147
+ # of the tzinfo class.
1148
+ delta = self._dst_offset - self._std_offset
1149
+ kwargs["seconds"] -= delta.seconds + delta.days * 86400
1150
+ return relativedelta.relativedelta(**kwargs)
1151
+
1152
+ def __repr__(self):
1153
+ return "%s(%s)" % (self.__class__.__name__, repr(self._s))
1154
+
1155
+
1156
+ class _tzicalvtzcomp(object):
1157
+ def __init__(self, tzoffsetfrom, tzoffsetto, isdst,
1158
+ tzname=None, rrule=None):
1159
+ self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom)
1160
+ self.tzoffsetto = datetime.timedelta(seconds=tzoffsetto)
1161
+ self.tzoffsetdiff = self.tzoffsetto - self.tzoffsetfrom
1162
+ self.isdst = isdst
1163
+ self.tzname = tzname
1164
+ self.rrule = rrule
1165
+
1166
+
1167
+ class _tzicalvtz(_tzinfo):
1168
+ def __init__(self, tzid, comps=[]):
1169
+ super(_tzicalvtz, self).__init__()
1170
+
1171
+ self._tzid = tzid
1172
+ self._comps = comps
1173
+ self._cachedate = []
1174
+ self._cachecomp = []
1175
+ self._cache_lock = _thread.allocate_lock()
1176
+
1177
+ def _find_comp(self, dt):
1178
+ if len(self._comps) == 1:
1179
+ return self._comps[0]
1180
+
1181
+ dt = dt.replace(tzinfo=None)
1182
+
1183
+ try:
1184
+ with self._cache_lock:
1185
+ return self._cachecomp[self._cachedate.index(
1186
+ (dt, self._fold(dt)))]
1187
+ except ValueError:
1188
+ pass
1189
+
1190
+ lastcompdt = None
1191
+ lastcomp = None
1192
+
1193
+ for comp in self._comps:
1194
+ compdt = self._find_compdt(comp, dt)
1195
+
1196
+ if compdt and (not lastcompdt or lastcompdt < compdt):
1197
+ lastcompdt = compdt
1198
+ lastcomp = comp
1199
+
1200
+ if not lastcomp:
1201
+ # RFC says nothing about what to do when a given
1202
+ # time is before the first onset date. We'll look for the
1203
+ # first standard component, or the first component, if
1204
+ # none is found.
1205
+ for comp in self._comps:
1206
+ if not comp.isdst:
1207
+ lastcomp = comp
1208
+ break
1209
+ else:
1210
+ lastcomp = comp[0]
1211
+
1212
+ with self._cache_lock:
1213
+ self._cachedate.insert(0, (dt, self._fold(dt)))
1214
+ self._cachecomp.insert(0, lastcomp)
1215
+
1216
+ if len(self._cachedate) > 10:
1217
+ self._cachedate.pop()
1218
+ self._cachecomp.pop()
1219
+
1220
+ return lastcomp
1221
+
1222
+ def _find_compdt(self, comp, dt):
1223
+ if comp.tzoffsetdiff < ZERO and self._fold(dt):
1224
+ dt -= comp.tzoffsetdiff
1225
+
1226
+ compdt = comp.rrule.before(dt, inc=True)
1227
+
1228
+ return compdt
1229
+
1230
+ def utcoffset(self, dt):
1231
+ if dt is None:
1232
+ return None
1233
+
1234
+ return self._find_comp(dt).tzoffsetto
1235
+
1236
+ def dst(self, dt):
1237
+ comp = self._find_comp(dt)
1238
+ if comp.isdst:
1239
+ return comp.tzoffsetdiff
1240
+ else:
1241
+ return ZERO
1242
+
1243
+ @tzname_in_python2
1244
+ def tzname(self, dt):
1245
+ return self._find_comp(dt).tzname
1246
+
1247
+ def __repr__(self):
1248
+ return "<tzicalvtz %s>" % repr(self._tzid)
1249
+
1250
+ __reduce__ = object.__reduce__
1251
+
1252
+
1253
+ class tzical(object):
1254
+ """
1255
+ This object is designed to parse an iCalendar-style ``VTIMEZONE`` structure
1256
+ as set out in `RFC 5545`_ Section 4.6.5 into one or more `tzinfo` objects.
1257
+
1258
+ :param `fileobj`:
1259
+ A file or stream in iCalendar format, which should be UTF-8 encoded
1260
+ with CRLF endings.
1261
+
1262
+ .. _`RFC 5545`: https://tools.ietf.org/html/rfc5545
1263
+ """
1264
+ def __init__(self, fileobj):
1265
+ global rrule
1266
+ from dateutil import rrule
1267
+
1268
+ if isinstance(fileobj, string_types):
1269
+ self._s = fileobj
1270
+ # ical should be encoded in UTF-8 with CRLF
1271
+ fileobj = open(fileobj, 'r')
1272
+ else:
1273
+ self._s = getattr(fileobj, 'name', repr(fileobj))
1274
+ fileobj = _nullcontext(fileobj)
1275
+
1276
+ self._vtz = {}
1277
+
1278
+ with fileobj as fobj:
1279
+ self._parse_rfc(fobj.read())
1280
+
1281
+ def keys(self):
1282
+ """
1283
+ Retrieves the available time zones as a list.
1284
+ """
1285
+ return list(self._vtz.keys())
1286
+
1287
+ def get(self, tzid=None):
1288
+ """
1289
+ Retrieve a :py:class:`datetime.tzinfo` object by its ``tzid``.
1290
+
1291
+ :param tzid:
1292
+ If there is exactly one time zone available, omitting ``tzid``
1293
+ or passing :py:const:`None` value returns it. Otherwise a valid
1294
+ key (which can be retrieved from :func:`keys`) is required.
1295
+
1296
+ :raises ValueError:
1297
+ Raised if ``tzid`` is not specified but there are either more
1298
+ or fewer than 1 zone defined.
1299
+
1300
+ :returns:
1301
+ Returns either a :py:class:`datetime.tzinfo` object representing
1302
+ the relevant time zone or :py:const:`None` if the ``tzid`` was
1303
+ not found.
1304
+ """
1305
+ if tzid is None:
1306
+ if len(self._vtz) == 0:
1307
+ raise ValueError("no timezones defined")
1308
+ elif len(self._vtz) > 1:
1309
+ raise ValueError("more than one timezone available")
1310
+ tzid = next(iter(self._vtz))
1311
+
1312
+ return self._vtz.get(tzid)
1313
+
1314
+ def _parse_offset(self, s):
1315
+ s = s.strip()
1316
+ if not s:
1317
+ raise ValueError("empty offset")
1318
+ if s[0] in ('+', '-'):
1319
+ signal = (-1, +1)[s[0] == '+']
1320
+ s = s[1:]
1321
+ else:
1322
+ signal = +1
1323
+ if len(s) == 4:
1324
+ return (int(s[:2]) * 3600 + int(s[2:]) * 60) * signal
1325
+ elif len(s) == 6:
1326
+ return (int(s[:2]) * 3600 + int(s[2:4]) * 60 + int(s[4:])) * signal
1327
+ else:
1328
+ raise ValueError("invalid offset: " + s)
1329
+
1330
+ def _parse_rfc(self, s):
1331
+ lines = s.splitlines()
1332
+ if not lines:
1333
+ raise ValueError("empty string")
1334
+
1335
+ # Unfold
1336
+ i = 0
1337
+ while i < len(lines):
1338
+ line = lines[i].rstrip()
1339
+ if not line:
1340
+ del lines[i]
1341
+ elif i > 0 and line[0] == " ":
1342
+ lines[i-1] += line[1:]
1343
+ del lines[i]
1344
+ else:
1345
+ i += 1
1346
+
1347
+ tzid = None
1348
+ comps = []
1349
+ invtz = False
1350
+ comptype = None
1351
+ for line in lines:
1352
+ if not line:
1353
+ continue
1354
+ name, value = line.split(':', 1)
1355
+ parms = name.split(';')
1356
+ if not parms:
1357
+ raise ValueError("empty property name")
1358
+ name = parms[0].upper()
1359
+ parms = parms[1:]
1360
+ if invtz:
1361
+ if name == "BEGIN":
1362
+ if value in ("STANDARD", "DAYLIGHT"):
1363
+ # Process component
1364
+ pass
1365
+ else:
1366
+ raise ValueError("unknown component: "+value)
1367
+ comptype = value
1368
+ founddtstart = False
1369
+ tzoffsetfrom = None
1370
+ tzoffsetto = None
1371
+ rrulelines = []
1372
+ tzname = None
1373
+ elif name == "END":
1374
+ if value == "VTIMEZONE":
1375
+ if comptype:
1376
+ raise ValueError("component not closed: "+comptype)
1377
+ if not tzid:
1378
+ raise ValueError("mandatory TZID not found")
1379
+ if not comps:
1380
+ raise ValueError(
1381
+ "at least one component is needed")
1382
+ # Process vtimezone
1383
+ self._vtz[tzid] = _tzicalvtz(tzid, comps)
1384
+ invtz = False
1385
+ elif value == comptype:
1386
+ if not founddtstart:
1387
+ raise ValueError("mandatory DTSTART not found")
1388
+ if tzoffsetfrom is None:
1389
+ raise ValueError(
1390
+ "mandatory TZOFFSETFROM not found")
1391
+ if tzoffsetto is None:
1392
+ raise ValueError(
1393
+ "mandatory TZOFFSETFROM not found")
1394
+ # Process component
1395
+ rr = None
1396
+ if rrulelines:
1397
+ rr = rrule.rrulestr("\n".join(rrulelines),
1398
+ compatible=True,
1399
+ ignoretz=True,
1400
+ cache=True)
1401
+ comp = _tzicalvtzcomp(tzoffsetfrom, tzoffsetto,
1402
+ (comptype == "DAYLIGHT"),
1403
+ tzname, rr)
1404
+ comps.append(comp)
1405
+ comptype = None
1406
+ else:
1407
+ raise ValueError("invalid component end: "+value)
1408
+ elif comptype:
1409
+ if name == "DTSTART":
1410
+ # DTSTART in VTIMEZONE takes a subset of valid RRULE
1411
+ # values under RFC 5545.
1412
+ for parm in parms:
1413
+ if parm != 'VALUE=DATE-TIME':
1414
+ msg = ('Unsupported DTSTART param in ' +
1415
+ 'VTIMEZONE: ' + parm)
1416
+ raise ValueError(msg)
1417
+ rrulelines.append(line)
1418
+ founddtstart = True
1419
+ elif name in ("RRULE", "RDATE", "EXRULE", "EXDATE"):
1420
+ rrulelines.append(line)
1421
+ elif name == "TZOFFSETFROM":
1422
+ if parms:
1423
+ raise ValueError(
1424
+ "unsupported %s parm: %s " % (name, parms[0]))
1425
+ tzoffsetfrom = self._parse_offset(value)
1426
+ elif name == "TZOFFSETTO":
1427
+ if parms:
1428
+ raise ValueError(
1429
+ "unsupported TZOFFSETTO parm: "+parms[0])
1430
+ tzoffsetto = self._parse_offset(value)
1431
+ elif name == "TZNAME":
1432
+ if parms:
1433
+ raise ValueError(
1434
+ "unsupported TZNAME parm: "+parms[0])
1435
+ tzname = value
1436
+ elif name == "COMMENT":
1437
+ pass
1438
+ else:
1439
+ raise ValueError("unsupported property: "+name)
1440
+ else:
1441
+ if name == "TZID":
1442
+ if parms:
1443
+ raise ValueError(
1444
+ "unsupported TZID parm: "+parms[0])
1445
+ tzid = value
1446
+ elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"):
1447
+ pass
1448
+ else:
1449
+ raise ValueError("unsupported property: "+name)
1450
+ elif name == "BEGIN" and value == "VTIMEZONE":
1451
+ tzid = None
1452
+ comps = []
1453
+ invtz = True
1454
+
1455
+ def __repr__(self):
1456
+ return "%s(%s)" % (self.__class__.__name__, repr(self._s))
1457
+
1458
+
1459
+ if sys.platform != "win32":
1460
+ TZFILES = ["/etc/localtime", "localtime"]
1461
+ TZPATHS = ["/usr/share/zoneinfo",
1462
+ "/usr/lib/zoneinfo",
1463
+ "/usr/share/lib/zoneinfo",
1464
+ "/etc/zoneinfo"]
1465
+ else:
1466
+ TZFILES = []
1467
+ TZPATHS = []
1468
+
1469
+
1470
+ def __get_gettz():
1471
+ tzlocal_classes = (tzlocal,)
1472
+ if tzwinlocal is not None:
1473
+ tzlocal_classes += (tzwinlocal,)
1474
+
1475
+ class GettzFunc(object):
1476
+ """
1477
+ Retrieve a time zone object from a string representation
1478
+
1479
+ This function is intended to retrieve the :py:class:`tzinfo` subclass
1480
+ that best represents the time zone that would be used if a POSIX
1481
+ `TZ variable`_ were set to the same value.
1482
+
1483
+ If no argument or an empty string is passed to ``gettz``, local time
1484
+ is returned:
1485
+
1486
+ .. code-block:: python3
1487
+
1488
+ >>> gettz()
1489
+ tzfile('/etc/localtime')
1490
+
1491
+ This function is also the preferred way to map IANA tz database keys
1492
+ to :class:`tzfile` objects:
1493
+
1494
+ .. code-block:: python3
1495
+
1496
+ >>> gettz('Pacific/Kiritimati')
1497
+ tzfile('/usr/share/zoneinfo/Pacific/Kiritimati')
1498
+
1499
+ On Windows, the standard is extended to include the Windows-specific
1500
+ zone names provided by the operating system:
1501
+
1502
+ .. code-block:: python3
1503
+
1504
+ >>> gettz('Egypt Standard Time')
1505
+ tzwin('Egypt Standard Time')
1506
+
1507
+ Passing a GNU ``TZ`` style string time zone specification returns a
1508
+ :class:`tzstr` object:
1509
+
1510
+ .. code-block:: python3
1511
+
1512
+ >>> gettz('AEST-10AEDT-11,M10.1.0/2,M4.1.0/3')
1513
+ tzstr('AEST-10AEDT-11,M10.1.0/2,M4.1.0/3')
1514
+
1515
+ :param name:
1516
+ A time zone name (IANA, or, on Windows, Windows keys), location of
1517
+ a ``tzfile(5)`` zoneinfo file or ``TZ`` variable style time zone
1518
+ specifier. An empty string, no argument or ``None`` is interpreted
1519
+ as local time.
1520
+
1521
+ :return:
1522
+ Returns an instance of one of ``dateutil``'s :py:class:`tzinfo`
1523
+ subclasses.
1524
+
1525
+ .. versionchanged:: 2.7.0
1526
+
1527
+ After version 2.7.0, any two calls to ``gettz`` using the same
1528
+ input strings will return the same object:
1529
+
1530
+ .. code-block:: python3
1531
+
1532
+ >>> tz.gettz('America/Chicago') is tz.gettz('America/Chicago')
1533
+ True
1534
+
1535
+ In addition to improving performance, this ensures that
1536
+ `"same zone" semantics`_ are used for datetimes in the same zone.
1537
+
1538
+
1539
+ .. _`TZ variable`:
1540
+ https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
1541
+
1542
+ .. _`"same zone" semantics`:
1543
+ https://blog.ganssle.io/articles/2018/02/aware-datetime-arithmetic.html
1544
+ """
1545
+ def __init__(self):
1546
+
1547
+ self.__instances = weakref.WeakValueDictionary()
1548
+ self.__strong_cache_size = 8
1549
+ self.__strong_cache = OrderedDict()
1550
+ self._cache_lock = _thread.allocate_lock()
1551
+
1552
+ def __call__(self, name=None):
1553
+ with self._cache_lock:
1554
+ rv = self.__instances.get(name, None)
1555
+
1556
+ if rv is None:
1557
+ rv = self.nocache(name=name)
1558
+ if not (name is None
1559
+ or isinstance(rv, tzlocal_classes)
1560
+ or rv is None):
1561
+ # tzlocal is slightly more complicated than the other
1562
+ # time zone providers because it depends on environment
1563
+ # at construction time, so don't cache that.
1564
+ #
1565
+ # We also cannot store weak references to None, so we
1566
+ # will also not store that.
1567
+ self.__instances[name] = rv
1568
+ else:
1569
+ # No need for strong caching, return immediately
1570
+ return rv
1571
+
1572
+ self.__strong_cache[name] = self.__strong_cache.pop(name, rv)
1573
+
1574
+ if len(self.__strong_cache) > self.__strong_cache_size:
1575
+ self.__strong_cache.popitem(last=False)
1576
+
1577
+ return rv
1578
+
1579
+ def set_cache_size(self, size):
1580
+ with self._cache_lock:
1581
+ self.__strong_cache_size = size
1582
+ while len(self.__strong_cache) > size:
1583
+ self.__strong_cache.popitem(last=False)
1584
+
1585
+ def cache_clear(self):
1586
+ with self._cache_lock:
1587
+ self.__instances = weakref.WeakValueDictionary()
1588
+ self.__strong_cache.clear()
1589
+
1590
+ @staticmethod
1591
+ def nocache(name=None):
1592
+ """A non-cached version of gettz"""
1593
+ tz = None
1594
+ if not name:
1595
+ try:
1596
+ name = os.environ["TZ"]
1597
+ except KeyError:
1598
+ pass
1599
+ if name is None or name in ("", ":"):
1600
+ for filepath in TZFILES:
1601
+ if not os.path.isabs(filepath):
1602
+ filename = filepath
1603
+ for path in TZPATHS:
1604
+ filepath = os.path.join(path, filename)
1605
+ if os.path.isfile(filepath):
1606
+ break
1607
+ else:
1608
+ continue
1609
+ if os.path.isfile(filepath):
1610
+ try:
1611
+ tz = tzfile(filepath)
1612
+ break
1613
+ except (IOError, OSError, ValueError):
1614
+ pass
1615
+ else:
1616
+ tz = tzlocal()
1617
+ else:
1618
+ try:
1619
+ if name.startswith(":"):
1620
+ name = name[1:]
1621
+ except TypeError as e:
1622
+ if isinstance(name, bytes):
1623
+ new_msg = "gettz argument should be str, not bytes"
1624
+ six.raise_from(TypeError(new_msg), e)
1625
+ else:
1626
+ raise
1627
+ if os.path.isabs(name):
1628
+ if os.path.isfile(name):
1629
+ tz = tzfile(name)
1630
+ else:
1631
+ tz = None
1632
+ else:
1633
+ for path in TZPATHS:
1634
+ filepath = os.path.join(path, name)
1635
+ if not os.path.isfile(filepath):
1636
+ filepath = filepath.replace(' ', '_')
1637
+ if not os.path.isfile(filepath):
1638
+ continue
1639
+ try:
1640
+ tz = tzfile(filepath)
1641
+ break
1642
+ except (IOError, OSError, ValueError):
1643
+ pass
1644
+ else:
1645
+ tz = None
1646
+ if tzwin is not None:
1647
+ try:
1648
+ tz = tzwin(name)
1649
+ except (WindowsError, UnicodeEncodeError):
1650
+ # UnicodeEncodeError is for Python 2.7 compat
1651
+ tz = None
1652
+
1653
+ if not tz:
1654
+ from dateutil.zoneinfo import get_zonefile_instance
1655
+ tz = get_zonefile_instance().get(name)
1656
+
1657
+ if not tz:
1658
+ for c in name:
1659
+ # name is not a tzstr unless it has at least
1660
+ # one offset. For short values of "name", an
1661
+ # explicit for loop seems to be the fastest way
1662
+ # To determine if a string contains a digit
1663
+ if c in "0123456789":
1664
+ try:
1665
+ tz = tzstr(name)
1666
+ except ValueError:
1667
+ pass
1668
+ break
1669
+ else:
1670
+ if name in ("GMT", "UTC"):
1671
+ tz = UTC
1672
+ elif name in time.tzname:
1673
+ tz = tzlocal()
1674
+ return tz
1675
+
1676
+ return GettzFunc()
1677
+
1678
+
1679
+ gettz = __get_gettz()
1680
+ del __get_gettz
1681
+
1682
+
1683
+ def datetime_exists(dt, tz=None):
1684
+ """
1685
+ Given a datetime and a time zone, determine whether or not a given datetime
1686
+ would fall in a gap.
1687
+
1688
+ :param dt:
1689
+ A :class:`datetime.datetime` (whose time zone will be ignored if ``tz``
1690
+ is provided.)
1691
+
1692
+ :param tz:
1693
+ A :class:`datetime.tzinfo` with support for the ``fold`` attribute. If
1694
+ ``None`` or not provided, the datetime's own time zone will be used.
1695
+
1696
+ :return:
1697
+ Returns a boolean value whether or not the "wall time" exists in
1698
+ ``tz``.
1699
+
1700
+ .. versionadded:: 2.7.0
1701
+ """
1702
+ if tz is None:
1703
+ if dt.tzinfo is None:
1704
+ raise ValueError('Datetime is naive and no time zone provided.')
1705
+ tz = dt.tzinfo
1706
+
1707
+ dt = dt.replace(tzinfo=None)
1708
+
1709
+ # This is essentially a test of whether or not the datetime can survive
1710
+ # a round trip to UTC.
1711
+ dt_rt = dt.replace(tzinfo=tz).astimezone(UTC).astimezone(tz)
1712
+ dt_rt = dt_rt.replace(tzinfo=None)
1713
+
1714
+ return dt == dt_rt
1715
+
1716
+
1717
+ def datetime_ambiguous(dt, tz=None):
1718
+ """
1719
+ Given a datetime and a time zone, determine whether or not a given datetime
1720
+ is ambiguous (i.e if there are two times differentiated only by their DST
1721
+ status).
1722
+
1723
+ :param dt:
1724
+ A :class:`datetime.datetime` (whose time zone will be ignored if ``tz``
1725
+ is provided.)
1726
+
1727
+ :param tz:
1728
+ A :class:`datetime.tzinfo` with support for the ``fold`` attribute. If
1729
+ ``None`` or not provided, the datetime's own time zone will be used.
1730
+
1731
+ :return:
1732
+ Returns a boolean value whether or not the "wall time" is ambiguous in
1733
+ ``tz``.
1734
+
1735
+ .. versionadded:: 2.6.0
1736
+ """
1737
+ if tz is None:
1738
+ if dt.tzinfo is None:
1739
+ raise ValueError('Datetime is naive and no time zone provided.')
1740
+
1741
+ tz = dt.tzinfo
1742
+
1743
+ # If a time zone defines its own "is_ambiguous" function, we'll use that.
1744
+ is_ambiguous_fn = getattr(tz, 'is_ambiguous', None)
1745
+ if is_ambiguous_fn is not None:
1746
+ try:
1747
+ return tz.is_ambiguous(dt)
1748
+ except Exception:
1749
+ pass
1750
+
1751
+ # If it doesn't come out and tell us it's ambiguous, we'll just check if
1752
+ # the fold attribute has any effect on this particular date and time.
1753
+ dt = dt.replace(tzinfo=tz)
1754
+ wall_0 = enfold(dt, fold=0)
1755
+ wall_1 = enfold(dt, fold=1)
1756
+
1757
+ same_offset = wall_0.utcoffset() == wall_1.utcoffset()
1758
+ same_dst = wall_0.dst() == wall_1.dst()
1759
+
1760
+ return not (same_offset and same_dst)
1761
+
1762
+
1763
+ def resolve_imaginary(dt):
1764
+ """
1765
+ Given a datetime that may be imaginary, return an existing datetime.
1766
+
1767
+ This function assumes that an imaginary datetime represents what the
1768
+ wall time would be in a zone had the offset transition not occurred, so
1769
+ it will always fall forward by the transition's change in offset.
1770
+
1771
+ .. doctest::
1772
+
1773
+ >>> from dateutil import tz
1774
+ >>> from datetime import datetime
1775
+ >>> NYC = tz.gettz('America/New_York')
1776
+ >>> print(tz.resolve_imaginary(datetime(2017, 3, 12, 2, 30, tzinfo=NYC)))
1777
+ 2017-03-12 03:30:00-04:00
1778
+
1779
+ >>> KIR = tz.gettz('Pacific/Kiritimati')
1780
+ >>> print(tz.resolve_imaginary(datetime(1995, 1, 1, 12, 30, tzinfo=KIR)))
1781
+ 1995-01-02 12:30:00+14:00
1782
+
1783
+ As a note, :func:`datetime.astimezone` is guaranteed to produce a valid,
1784
+ existing datetime, so a round-trip to and from UTC is sufficient to get
1785
+ an extant datetime, however, this generally "falls back" to an earlier time
1786
+ rather than falling forward to the STD side (though no guarantees are made
1787
+ about this behavior).
1788
+
1789
+ :param dt:
1790
+ A :class:`datetime.datetime` which may or may not exist.
1791
+
1792
+ :return:
1793
+ Returns an existing :class:`datetime.datetime`. If ``dt`` was not
1794
+ imaginary, the datetime returned is guaranteed to be the same object
1795
+ passed to the function.
1796
+
1797
+ .. versionadded:: 2.7.0
1798
+ """
1799
+ if dt.tzinfo is not None and not datetime_exists(dt):
1800
+
1801
+ curr_offset = (dt + datetime.timedelta(hours=24)).utcoffset()
1802
+ old_offset = (dt - datetime.timedelta(hours=24)).utcoffset()
1803
+
1804
+ dt += curr_offset - old_offset
1805
+
1806
+ return dt
1807
+
1808
+
1809
+ def _datetime_to_timestamp(dt):
1810
+ """
1811
+ Convert a :class:`datetime.datetime` object to an epoch timestamp in
1812
+ seconds since January 1, 1970, ignoring the time zone.
1813
+ """
1814
+ return (dt.replace(tzinfo=None) - EPOCH).total_seconds()
1815
+
1816
+
1817
+ if sys.version_info >= (3, 6):
1818
+ def _get_supported_offset(second_offset):
1819
+ return second_offset
1820
+ else:
1821
+ def _get_supported_offset(second_offset):
1822
+ # For python pre-3.6, round to full-minutes if that's not the case.
1823
+ # Python's datetime doesn't accept sub-minute timezones. Check
1824
+ # http://python.org/sf/1447945 or https://bugs.python.org/issue5288
1825
+ # for some information.
1826
+ old_offset = second_offset
1827
+ calculated_offset = 60 * ((second_offset + 30) // 60)
1828
+ return calculated_offset
1829
+
1830
+
1831
+ try:
1832
+ # Python 3.7 feature
1833
+ from contextlib import nullcontext as _nullcontext
1834
+ except ImportError:
1835
+ class _nullcontext(object):
1836
+ """
1837
+ Class for wrapping contexts so that they are passed through in a
1838
+ with statement.
1839
+ """
1840
+ def __init__(self, context):
1841
+ self.context = context
1842
+
1843
+ def __enter__(self):
1844
+ return self.context
1845
+
1846
+ def __exit__(*args, **kwargs):
1847
+ pass
1848
+
1849
+ # vim:ts=4:sw=4:et
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/tz/win.py ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ This module provides an interface to the native time zone data on Windows,
4
+ including :py:class:`datetime.tzinfo` implementations.
5
+
6
+ Attempting to import this module on a non-Windows platform will raise an
7
+ :py:obj:`ImportError`.
8
+ """
9
+ # This code was originally contributed by Jeffrey Harris.
10
+ import datetime
11
+ import struct
12
+
13
+ from six.moves import winreg
14
+ from six import text_type
15
+
16
+ try:
17
+ import ctypes
18
+ from ctypes import wintypes
19
+ except ValueError:
20
+ # ValueError is raised on non-Windows systems for some horrible reason.
21
+ raise ImportError("Running tzwin on non-Windows system")
22
+
23
+ from ._common import tzrangebase
24
+
25
+ __all__ = ["tzwin", "tzwinlocal", "tzres"]
26
+
27
+ ONEWEEK = datetime.timedelta(7)
28
+
29
+ TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
30
+ TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"
31
+ TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
32
+
33
+
34
+ def _settzkeyname():
35
+ handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
36
+ try:
37
+ winreg.OpenKey(handle, TZKEYNAMENT).Close()
38
+ TZKEYNAME = TZKEYNAMENT
39
+ except WindowsError:
40
+ TZKEYNAME = TZKEYNAME9X
41
+ handle.Close()
42
+ return TZKEYNAME
43
+
44
+
45
+ TZKEYNAME = _settzkeyname()
46
+
47
+
48
+ class tzres(object):
49
+ """
50
+ Class for accessing ``tzres.dll``, which contains timezone name related
51
+ resources.
52
+
53
+ .. versionadded:: 2.5.0
54
+ """
55
+ p_wchar = ctypes.POINTER(wintypes.WCHAR) # Pointer to a wide char
56
+
57
+ def __init__(self, tzres_loc='tzres.dll'):
58
+ # Load the user32 DLL so we can load strings from tzres
59
+ user32 = ctypes.WinDLL('user32')
60
+
61
+ # Specify the LoadStringW function
62
+ user32.LoadStringW.argtypes = (wintypes.HINSTANCE,
63
+ wintypes.UINT,
64
+ wintypes.LPWSTR,
65
+ ctypes.c_int)
66
+
67
+ self.LoadStringW = user32.LoadStringW
68
+ self._tzres = ctypes.WinDLL(tzres_loc)
69
+ self.tzres_loc = tzres_loc
70
+
71
+ def load_name(self, offset):
72
+ """
73
+ Load a timezone name from a DLL offset (integer).
74
+
75
+ >>> from dateutil.tzwin import tzres
76
+ >>> tzr = tzres()
77
+ >>> print(tzr.load_name(112))
78
+ 'Eastern Standard Time'
79
+
80
+ :param offset:
81
+ A positive integer value referring to a string from the tzres dll.
82
+
83
+ .. note::
84
+
85
+ Offsets found in the registry are generally of the form
86
+ ``@tzres.dll,-114``. The offset in this case is 114, not -114.
87
+
88
+ """
89
+ resource = self.p_wchar()
90
+ lpBuffer = ctypes.cast(ctypes.byref(resource), wintypes.LPWSTR)
91
+ nchar = self.LoadStringW(self._tzres._handle, offset, lpBuffer, 0)
92
+ return resource[:nchar]
93
+
94
+ def name_from_string(self, tzname_str):
95
+ """
96
+ Parse strings as returned from the Windows registry into the time zone
97
+ name as defined in the registry.
98
+
99
+ >>> from dateutil.tzwin import tzres
100
+ >>> tzr = tzres()
101
+ >>> print(tzr.name_from_string('@tzres.dll,-251'))
102
+ 'Dateline Daylight Time'
103
+ >>> print(tzr.name_from_string('Eastern Standard Time'))
104
+ 'Eastern Standard Time'
105
+
106
+ :param tzname_str:
107
+ A timezone name string as returned from a Windows registry key.
108
+
109
+ :return:
110
+ Returns the localized timezone string from tzres.dll if the string
111
+ is of the form `@tzres.dll,-offset`, else returns the input string.
112
+ """
113
+ if not tzname_str.startswith('@'):
114
+ return tzname_str
115
+
116
+ name_splt = tzname_str.split(',-')
117
+ try:
118
+ offset = int(name_splt[1])
119
+ except:
120
+ raise ValueError("Malformed timezone string.")
121
+
122
+ return self.load_name(offset)
123
+
124
+
125
+ class tzwinbase(tzrangebase):
126
+ """tzinfo class based on win32's timezones available in the registry."""
127
+ def __init__(self):
128
+ raise NotImplementedError('tzwinbase is an abstract base class')
129
+
130
+ def __eq__(self, other):
131
+ # Compare on all relevant dimensions, including name.
132
+ if not isinstance(other, tzwinbase):
133
+ return NotImplemented
134
+
135
+ return (self._std_offset == other._std_offset and
136
+ self._dst_offset == other._dst_offset and
137
+ self._stddayofweek == other._stddayofweek and
138
+ self._dstdayofweek == other._dstdayofweek and
139
+ self._stdweeknumber == other._stdweeknumber and
140
+ self._dstweeknumber == other._dstweeknumber and
141
+ self._stdhour == other._stdhour and
142
+ self._dsthour == other._dsthour and
143
+ self._stdminute == other._stdminute and
144
+ self._dstminute == other._dstminute and
145
+ self._std_abbr == other._std_abbr and
146
+ self._dst_abbr == other._dst_abbr)
147
+
148
+ @staticmethod
149
+ def list():
150
+ """Return a list of all time zones known to the system."""
151
+ with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
152
+ with winreg.OpenKey(handle, TZKEYNAME) as tzkey:
153
+ result = [winreg.EnumKey(tzkey, i)
154
+ for i in range(winreg.QueryInfoKey(tzkey)[0])]
155
+ return result
156
+
157
+ def display(self):
158
+ """
159
+ Return the display name of the time zone.
160
+ """
161
+ return self._display
162
+
163
+ def transitions(self, year):
164
+ """
165
+ For a given year, get the DST on and off transition times, expressed
166
+ always on the standard time side. For zones with no transitions, this
167
+ function returns ``None``.
168
+
169
+ :param year:
170
+ The year whose transitions you would like to query.
171
+
172
+ :return:
173
+ Returns a :class:`tuple` of :class:`datetime.datetime` objects,
174
+ ``(dston, dstoff)`` for zones with an annual DST transition, or
175
+ ``None`` for fixed offset zones.
176
+ """
177
+
178
+ if not self.hasdst:
179
+ return None
180
+
181
+ dston = picknthweekday(year, self._dstmonth, self._dstdayofweek,
182
+ self._dsthour, self._dstminute,
183
+ self._dstweeknumber)
184
+
185
+ dstoff = picknthweekday(year, self._stdmonth, self._stddayofweek,
186
+ self._stdhour, self._stdminute,
187
+ self._stdweeknumber)
188
+
189
+ # Ambiguous dates default to the STD side
190
+ dstoff -= self._dst_base_offset
191
+
192
+ return dston, dstoff
193
+
194
+ def _get_hasdst(self):
195
+ return self._dstmonth != 0
196
+
197
+ @property
198
+ def _dst_base_offset(self):
199
+ return self._dst_base_offset_
200
+
201
+
202
+ class tzwin(tzwinbase):
203
+ """
204
+ Time zone object created from the zone info in the Windows registry
205
+
206
+ These are similar to :py:class:`dateutil.tz.tzrange` objects in that
207
+ the time zone data is provided in the format of a single offset rule
208
+ for either 0 or 2 time zone transitions per year.
209
+
210
+ :param: name
211
+ The name of a Windows time zone key, e.g. "Eastern Standard Time".
212
+ The full list of keys can be retrieved with :func:`tzwin.list`.
213
+ """
214
+
215
+ def __init__(self, name):
216
+ self._name = name
217
+
218
+ with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
219
+ tzkeyname = text_type("{kn}\\{name}").format(kn=TZKEYNAME, name=name)
220
+ with winreg.OpenKey(handle, tzkeyname) as tzkey:
221
+ keydict = valuestodict(tzkey)
222
+
223
+ self._std_abbr = keydict["Std"]
224
+ self._dst_abbr = keydict["Dlt"]
225
+
226
+ self._display = keydict["Display"]
227
+
228
+ # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm
229
+ tup = struct.unpack("=3l16h", keydict["TZI"])
230
+ stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1
231
+ dstoffset = stdoffset-tup[2] # + DaylightBias * -1
232
+ self._std_offset = datetime.timedelta(minutes=stdoffset)
233
+ self._dst_offset = datetime.timedelta(minutes=dstoffset)
234
+
235
+ # for the meaning see the win32 TIME_ZONE_INFORMATION structure docs
236
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
237
+ (self._stdmonth,
238
+ self._stddayofweek, # Sunday = 0
239
+ self._stdweeknumber, # Last = 5
240
+ self._stdhour,
241
+ self._stdminute) = tup[4:9]
242
+
243
+ (self._dstmonth,
244
+ self._dstdayofweek, # Sunday = 0
245
+ self._dstweeknumber, # Last = 5
246
+ self._dsthour,
247
+ self._dstminute) = tup[12:17]
248
+
249
+ self._dst_base_offset_ = self._dst_offset - self._std_offset
250
+ self.hasdst = self._get_hasdst()
251
+
252
+ def __repr__(self):
253
+ return "tzwin(%s)" % repr(self._name)
254
+
255
+ def __reduce__(self):
256
+ return (self.__class__, (self._name,))
257
+
258
+
259
+ class tzwinlocal(tzwinbase):
260
+ """
261
+ Class representing the local time zone information in the Windows registry
262
+
263
+ While :class:`dateutil.tz.tzlocal` makes system calls (via the :mod:`time`
264
+ module) to retrieve time zone information, ``tzwinlocal`` retrieves the
265
+ rules directly from the Windows registry and creates an object like
266
+ :class:`dateutil.tz.tzwin`.
267
+
268
+ Because Windows does not have an equivalent of :func:`time.tzset`, on
269
+ Windows, :class:`dateutil.tz.tzlocal` instances will always reflect the
270
+ time zone settings *at the time that the process was started*, meaning
271
+ changes to the machine's time zone settings during the run of a program
272
+ on Windows will **not** be reflected by :class:`dateutil.tz.tzlocal`.
273
+ Because ``tzwinlocal`` reads the registry directly, it is unaffected by
274
+ this issue.
275
+ """
276
+ def __init__(self):
277
+ with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
278
+ with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey:
279
+ keydict = valuestodict(tzlocalkey)
280
+
281
+ self._std_abbr = keydict["StandardName"]
282
+ self._dst_abbr = keydict["DaylightName"]
283
+
284
+ try:
285
+ tzkeyname = text_type('{kn}\\{sn}').format(kn=TZKEYNAME,
286
+ sn=self._std_abbr)
287
+ with winreg.OpenKey(handle, tzkeyname) as tzkey:
288
+ _keydict = valuestodict(tzkey)
289
+ self._display = _keydict["Display"]
290
+ except OSError:
291
+ self._display = None
292
+
293
+ stdoffset = -keydict["Bias"]-keydict["StandardBias"]
294
+ dstoffset = stdoffset-keydict["DaylightBias"]
295
+
296
+ self._std_offset = datetime.timedelta(minutes=stdoffset)
297
+ self._dst_offset = datetime.timedelta(minutes=dstoffset)
298
+
299
+ # For reasons unclear, in this particular key, the day of week has been
300
+ # moved to the END of the SYSTEMTIME structure.
301
+ tup = struct.unpack("=8h", keydict["StandardStart"])
302
+
303
+ (self._stdmonth,
304
+ self._stdweeknumber, # Last = 5
305
+ self._stdhour,
306
+ self._stdminute) = tup[1:5]
307
+
308
+ self._stddayofweek = tup[7]
309
+
310
+ tup = struct.unpack("=8h", keydict["DaylightStart"])
311
+
312
+ (self._dstmonth,
313
+ self._dstweeknumber, # Last = 5
314
+ self._dsthour,
315
+ self._dstminute) = tup[1:5]
316
+
317
+ self._dstdayofweek = tup[7]
318
+
319
+ self._dst_base_offset_ = self._dst_offset - self._std_offset
320
+ self.hasdst = self._get_hasdst()
321
+
322
+ def __repr__(self):
323
+ return "tzwinlocal()"
324
+
325
+ def __str__(self):
326
+ # str will return the standard name, not the daylight name.
327
+ return "tzwinlocal(%s)" % repr(self._std_abbr)
328
+
329
+ def __reduce__(self):
330
+ return (self.__class__, ())
331
+
332
+
333
+ def picknthweekday(year, month, dayofweek, hour, minute, whichweek):
334
+ """ dayofweek == 0 means Sunday, whichweek 5 means last instance """
335
+ first = datetime.datetime(year, month, 1, hour, minute)
336
+
337
+ # This will work if dayofweek is ISO weekday (1-7) or Microsoft-style (0-6),
338
+ # Because 7 % 7 = 0
339
+ weekdayone = first.replace(day=((dayofweek - first.isoweekday()) % 7) + 1)
340
+ wd = weekdayone + ((whichweek - 1) * ONEWEEK)
341
+ if (wd.month != month):
342
+ wd -= ONEWEEK
343
+
344
+ return wd
345
+
346
+
347
+ def valuestodict(key):
348
+ """Convert a registry key's values to a dictionary."""
349
+ dout = {}
350
+ size = winreg.QueryInfoKey(key)[1]
351
+ tz_res = None
352
+
353
+ for i in range(size):
354
+ key_name, value, dtype = winreg.EnumValue(key, i)
355
+ if dtype == winreg.REG_DWORD or dtype == winreg.REG_DWORD_LITTLE_ENDIAN:
356
+ # If it's a DWORD (32-bit integer), it's stored as unsigned - convert
357
+ # that to a proper signed integer
358
+ if value & (1 << 31):
359
+ value = value - (1 << 32)
360
+ elif dtype == winreg.REG_SZ:
361
+ # If it's a reference to the tzres DLL, load the actual string
362
+ if value.startswith('@tzres'):
363
+ tz_res = tz_res or tzres()
364
+ value = tz_res.name_from_string(value)
365
+
366
+ value = value.rstrip('\x00') # Remove trailing nulls
367
+
368
+ dout[key_name] = value
369
+
370
+ return dout
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/dateutil/zoneinfo/__init__.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import warnings
3
+ import json
4
+
5
+ from tarfile import TarFile
6
+ from pkgutil import get_data
7
+ from io import BytesIO
8
+
9
+ from dateutil.tz import tzfile as _tzfile
10
+
11
+ __all__ = ["get_zonefile_instance", "gettz", "gettz_db_metadata"]
12
+
13
+ ZONEFILENAME = "dateutil-zoneinfo.tar.gz"
14
+ METADATA_FN = 'METADATA'
15
+
16
+
17
+ class tzfile(_tzfile):
18
+ def __reduce__(self):
19
+ return (gettz, (self._filename,))
20
+
21
+
22
+ def getzoneinfofile_stream():
23
+ try:
24
+ return BytesIO(get_data(__name__, ZONEFILENAME))
25
+ except IOError as e: # TODO switch to FileNotFoundError?
26
+ warnings.warn("I/O error({0}): {1}".format(e.errno, e.strerror))
27
+ return None
28
+
29
+
30
+ class ZoneInfoFile(object):
31
+ def __init__(self, zonefile_stream=None):
32
+ if zonefile_stream is not None:
33
+ with TarFile.open(fileobj=zonefile_stream) as tf:
34
+ self.zones = {zf.name: tzfile(tf.extractfile(zf), filename=zf.name)
35
+ for zf in tf.getmembers()
36
+ if zf.isfile() and zf.name != METADATA_FN}
37
+ # deal with links: They'll point to their parent object. Less
38
+ # waste of memory
39
+ links = {zl.name: self.zones[zl.linkname]
40
+ for zl in tf.getmembers() if
41
+ zl.islnk() or zl.issym()}
42
+ self.zones.update(links)
43
+ try:
44
+ metadata_json = tf.extractfile(tf.getmember(METADATA_FN))
45
+ metadata_str = metadata_json.read().decode('UTF-8')
46
+ self.metadata = json.loads(metadata_str)
47
+ except KeyError:
48
+ # no metadata in tar file
49
+ self.metadata = None
50
+ else:
51
+ self.zones = {}
52
+ self.metadata = None
53
+
54
+ def get(self, name, default=None):
55
+ """
56
+ Wrapper for :func:`ZoneInfoFile.zones.get`. This is a convenience method
57
+ for retrieving zones from the zone dictionary.
58
+
59
+ :param name:
60
+ The name of the zone to retrieve. (Generally IANA zone names)
61
+
62
+ :param default:
63
+ The value to return in the event of a missing key.
64
+
65
+ .. versionadded:: 2.6.0
66
+
67
+ """
68
+ return self.zones.get(name, default)
69
+
70
+
71
+ # The current API has gettz as a module function, although in fact it taps into
72
+ # a stateful class. So as a workaround for now, without changing the API, we
73
+ # will create a new "global" class instance the first time a user requests a
74
+ # timezone. Ugly, but adheres to the api.
75
+ #
76
+ # TODO: Remove after deprecation period.
77
+ _CLASS_ZONE_INSTANCE = []
78
+
79
+
80
+ def get_zonefile_instance(new_instance=False):
81
+ """
82
+ This is a convenience function which provides a :class:`ZoneInfoFile`
83
+ instance using the data provided by the ``dateutil`` package. By default, it
84
+ caches a single instance of the ZoneInfoFile object and returns that.
85
+
86
+ :param new_instance:
87
+ If ``True``, a new instance of :class:`ZoneInfoFile` is instantiated and
88
+ used as the cached instance for the next call. Otherwise, new instances
89
+ are created only as necessary.
90
+
91
+ :return:
92
+ Returns a :class:`ZoneInfoFile` object.
93
+
94
+ .. versionadded:: 2.6
95
+ """
96
+ if new_instance:
97
+ zif = None
98
+ else:
99
+ zif = getattr(get_zonefile_instance, '_cached_instance', None)
100
+
101
+ if zif is None:
102
+ zif = ZoneInfoFile(getzoneinfofile_stream())
103
+
104
+ get_zonefile_instance._cached_instance = zif
105
+
106
+ return zif
107
+
108
+
109
+ def gettz(name):
110
+ """
111
+ This retrieves a time zone from the local zoneinfo tarball that is packaged
112
+ with dateutil.
113
+
114
+ :param name:
115
+ An IANA-style time zone name, as found in the zoneinfo file.
116
+
117
+ :return:
118
+ Returns a :class:`dateutil.tz.tzfile` time zone object.
119
+
120
+ .. warning::
121
+ It is generally inadvisable to use this function, and it is only
122
+ provided for API compatibility with earlier versions. This is *not*
123
+ equivalent to ``dateutil.tz.gettz()``, which selects an appropriate
124
+ time zone based on the inputs, favoring system zoneinfo. This is ONLY
125
+ for accessing the dateutil-specific zoneinfo (which may be out of
126
+ date compared to the system zoneinfo).
127
+
128
+ .. deprecated:: 2.6
129
+ If you need to use a specific zoneinfofile over the system zoneinfo,
130
+ instantiate a :class:`dateutil.zoneinfo.ZoneInfoFile` object and call
131
+ :func:`dateutil.zoneinfo.ZoneInfoFile.get(name)` instead.
132
+
133
+ Use :func:`get_zonefile_instance` to retrieve an instance of the
134
+ dateutil-provided zoneinfo.
135
+ """
136
+ warnings.warn("zoneinfo.gettz() will be removed in future versions, "
137
+ "to use the dateutil-provided zoneinfo files, instantiate a "
138
+ "ZoneInfoFile object and use ZoneInfoFile.zones.get() "
139
+ "instead. See the documentation for details.",
140
+ DeprecationWarning)
141
+
142
+ if len(_CLASS_ZONE_INSTANCE) == 0:
143
+ _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream()))
144
+ return _CLASS_ZONE_INSTANCE[0].zones.get(name)
145
+
146
+
147
+ def gettz_db_metadata():
148
+ """ Get the zonefile metadata
149
+
150
+ See `zonefile_metadata`_
151
+
152
+ :returns:
153
+ A dictionary with the database metadata
154
+
155
+ .. deprecated:: 2.6
156
+ See deprecation warning in :func:`zoneinfo.gettz`. To get metadata,
157
+ query the attribute ``zoneinfo.ZoneInfoFile.metadata``.
158
+ """
159
+ warnings.warn("zoneinfo.gettz_db_metadata() will be removed in future "
160
+ "versions, to use the dateutil-provided zoneinfo files, "
161
+ "ZoneInfoFile object and query the 'metadata' attribute "
162
+ "instead. See the documentation for details.",
163
+ DeprecationWarning)
164
+
165
+ if len(_CLASS_ZONE_INSTANCE) == 0:
166
+ _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream()))
167
+ return _CLASS_ZONE_INSTANCE[0].metadata
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (1.51 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/config.cpython-312.pyc ADDED
Binary file (7.56 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/hub.cpython-312.pyc ADDED
Binary file (4.94 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/info.cpython-312.pyc ADDED
Binary file (7.37 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/inspect.cpython-312.pyc ADDED
Binary file (4.92 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/loading.cpython-312.pyc ADDED
Binary file (37.1 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/module.cpython-312.pyc ADDED
Binary file (55.4 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/naming.cpython-312.pyc ADDED
Binary file (3.74 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/saving.cpython-312.pyc ADDED
Binary file (3.58 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/__pycache__/visualization.cpython-312.pyc ADDED
Binary file (11.9 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/commands/__init__.py ADDED
File without changes
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/commands/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (223 Bytes). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/commands/__pycache__/evaluate_cli.cpython-312.pyc ADDED
Binary file (5.61 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/commands/evaluate_cli.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import os
3
+ import subprocess
4
+ from pathlib import Path
5
+
6
+ from cookiecutter.main import cookiecutter
7
+ from huggingface_hub import HfApi, Repository, create_repo
8
+
9
+ from evaluate.utils.logging import get_logger
10
+
11
+
12
+ logger = get_logger(__name__)
13
+
14
+ INSTRUCTIONS = """\
15
+ A new repository for your module "{module_name}" of type "{module_type}" has been created at {output_dir} and pushed to the Hugging Face Hub: {repo_url}.
16
+
17
+ Here are the next steps:
18
+ - implement the module logic in {module_slug}/{module_slug}.py
19
+ - document your module in {module_slug}/README.md
20
+ - add test cases for your module in {module_slug}/tests.py
21
+ - if your module has any dependencies update them in {module_slug}/requirements.txt
22
+
23
+ You can test your module's widget locally by running:
24
+
25
+ ```
26
+ python {output_dir}/{module_slug}/app.py
27
+ ```
28
+
29
+ When you are happy with your changes you can push your changes with the following commands to the Hugging Face Hub:
30
+
31
+ ```
32
+ cd {output_dir}/{module_slug}
33
+ git add .
34
+ git commit -m "Updating module"
35
+ git push
36
+ ```
37
+
38
+ You should then see the update widget on the Hugging Face Hub: {repo_url}
39
+ And you can load your module in Python with the following code:
40
+
41
+ ```
42
+ from evaluate import load
43
+ module = load("{namespace}/{module_slug}")
44
+ ```
45
+ """
46
+
47
+
48
+ def main():
49
+ parser = argparse.ArgumentParser("HuggingFace Evaluate CLI tool", usage="evaluate-cli <command> [<args>]")
50
+ subparsers = parser.add_subparsers()
51
+ parser_create = subparsers.add_parser("create", help="Create new evaluation module.")
52
+ parser_create.add_argument(
53
+ "module_name", type=str, help='Pretty name of new evaluation module, e.g. "Recall" or "Exact Match".'
54
+ )
55
+ parser_create.add_argument(
56
+ "--module_type",
57
+ default="metric",
58
+ type=str,
59
+ help="Type of module, has to be one of [metric|comparison|measurement].",
60
+ )
61
+ parser_create.add_argument(
62
+ "--dataset_name", default="", type=str, help="Name of dataset if evaluation module is dataset specific."
63
+ )
64
+ parser_create.add_argument("--module_description", type=str, help="Short description of evaluation module.")
65
+ parser_create.add_argument("--output_dir", default=Path.cwd(), type=str, help="Path to output directory.")
66
+ parser_create.add_argument(
67
+ "--organization", default=None, type=str, help="Organization on the Hub to push evaluation module to."
68
+ )
69
+ parser_create.add_argument("--private", action="store_true", help="Sets evaluation module repository to private.")
70
+ args = vars(parser.parse_args())
71
+
72
+ if args["module_type"] not in ["metric", "comparison", "measurement"]:
73
+ raise ValueError("The module_type needs to be one of metric, comparison, or measurement")
74
+
75
+ if "-" in args["module_name"]:
76
+ raise ValueError("Hyphens ('-') are not allowed in module names.")
77
+
78
+ output_dir = Path(args["output_dir"])
79
+ organization = args["organization"]
80
+ module_slug = args["module_name"].lower().replace(" ", "_")
81
+
82
+ if organization is None:
83
+ hfapi = HfApi()
84
+ namespace = hfapi.whoami()["name"]
85
+ else:
86
+ namespace = organization
87
+ args["namespace"] = namespace
88
+ repo_url = f"https://huggingface.co/spaces/{namespace}/{module_slug}"
89
+
90
+ try:
91
+ create_repo(namespace + "/" + module_slug, repo_type="space", space_sdk="gradio", private=args["private"])
92
+ except Exception as exception:
93
+ logger.error(
94
+ f"Could not create Space for module at hf.co/spaces/{namespace}/{module_slug}. Make sure this space does not exist already."
95
+ )
96
+ raise exception
97
+ subprocess.run(
98
+ f"git clone {repo_url}".split(),
99
+ stderr=subprocess.PIPE,
100
+ stdout=subprocess.PIPE,
101
+ check=True,
102
+ encoding="utf-8",
103
+ cwd=output_dir,
104
+ env=os.environ.copy(),
105
+ )
106
+
107
+ repo = Repository(
108
+ local_dir=output_dir / module_slug,
109
+ )
110
+
111
+ cookiecutter(
112
+ "https://github.com/huggingface/evaluate/",
113
+ directory="templates",
114
+ no_input=True,
115
+ extra_context=args,
116
+ output_dir=output_dir,
117
+ overwrite_if_exists=True,
118
+ )
119
+
120
+ repo.git_add()
121
+ repo.git_commit("add module default template")
122
+ repo.git_push()
123
+
124
+ print(
125
+ INSTRUCTIONS.format(
126
+ module_name=args["module_name"],
127
+ module_type=args["module_type"],
128
+ module_slug=module_slug,
129
+ namespace=namespace,
130
+ repo_url=repo_url,
131
+ output_dir=output_dir,
132
+ )
133
+ )
134
+
135
+
136
+ if __name__ == "__main__":
137
+ main()
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluation_suite/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (7.41 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__init__.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 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
+
16
+ try:
17
+ from transformers.pipelines import SUPPORTED_TASKS as SUPPORTED_PIPELINE_TASKS
18
+ from transformers.pipelines import TASK_ALIASES
19
+ from transformers.pipelines import check_task as check_pipeline_task
20
+
21
+ TRANSFORMERS_AVAILABLE = True
22
+ except ImportError:
23
+ TRANSFORMERS_AVAILABLE = False
24
+
25
+ from typing import Dict, List
26
+
27
+ from .audio_classification import AudioClassificationEvaluator
28
+ from .automatic_speech_recognition import AutomaticSpeechRecognitionEvaluator
29
+ from .base import Evaluator
30
+ from .image_classification import ImageClassificationEvaluator
31
+ from .question_answering import QuestionAnsweringEvaluator
32
+ from .text2text_generation import SummarizationEvaluator, Text2TextGenerationEvaluator, TranslationEvaluator
33
+ from .text_classification import TextClassificationEvaluator
34
+ from .text_generation import TextGenerationEvaluator
35
+ from .token_classification import TokenClassificationEvaluator
36
+
37
+
38
+ SUPPORTED_EVALUATOR_TASKS = {
39
+ "text-classification": {
40
+ "implementation": TextClassificationEvaluator,
41
+ "default_metric_name": "accuracy",
42
+ },
43
+ "image-classification": {
44
+ "implementation": ImageClassificationEvaluator,
45
+ "default_metric_name": "accuracy",
46
+ },
47
+ "question-answering": {
48
+ "implementation": QuestionAnsweringEvaluator,
49
+ "default_metric_name": "squad",
50
+ },
51
+ "token-classification": {
52
+ "implementation": TokenClassificationEvaluator,
53
+ "default_metric_name": "seqeval",
54
+ },
55
+ "text-generation": {
56
+ "implementation": TextGenerationEvaluator,
57
+ "default_metric_name": "word_count",
58
+ },
59
+ "text2text-generation": {
60
+ "implementation": Text2TextGenerationEvaluator,
61
+ "default_metric_name": "bleu",
62
+ },
63
+ "summarization": {
64
+ "implementation": SummarizationEvaluator,
65
+ "default_metric_name": "rouge",
66
+ },
67
+ "translation": {
68
+ "implementation": TranslationEvaluator,
69
+ "default_metric_name": "bleu",
70
+ },
71
+ "automatic-speech-recognition": {
72
+ "implementation": AutomaticSpeechRecognitionEvaluator,
73
+ "default_metric_name": "wer",
74
+ },
75
+ "audio-classification": {
76
+ "implementation": AudioClassificationEvaluator,
77
+ "default_metric_name": "accuracy",
78
+ },
79
+ }
80
+
81
+
82
+ def get_supported_tasks() -> List[str]:
83
+ """
84
+ Returns a list of supported task strings.
85
+ """
86
+ return list(SUPPORTED_EVALUATOR_TASKS.keys())
87
+
88
+
89
+ def check_task(task: str) -> Dict:
90
+ """
91
+ Checks an incoming task string, to validate it's correct and returns the default Evaluator class and default metric
92
+ name. It first performs a check to validata that the string is a valid `Pipeline` task, then it checks if it's a
93
+ valid `Evaluator` task. `Evaluator` tasks are a substet of `Pipeline` tasks.
94
+ Args:
95
+ task (`str`):
96
+ The task defining which evaluator will be returned. Currently accepted tasks are:
97
+ - `"image-classification"`
98
+ - `"question-answering"`
99
+ - `"text-classification"` (alias `"sentiment-analysis"` available)
100
+ - `"token-classification"`
101
+ Returns:
102
+ task_defaults: `dict`, contains the implementasion class of a give Evaluator and the default metric name.
103
+ """
104
+ if task in TASK_ALIASES:
105
+ task = TASK_ALIASES[task]
106
+ if not check_pipeline_task(task):
107
+ raise KeyError(f"Unknown task {task}, available tasks are: {get_supported_tasks()}.")
108
+ if task in SUPPORTED_EVALUATOR_TASKS.keys() and task in SUPPORTED_PIPELINE_TASKS.keys():
109
+ return SUPPORTED_EVALUATOR_TASKS[task]
110
+ raise KeyError(f"Unknown task {task}, available tasks are: {get_supported_tasks()}.")
111
+
112
+
113
+ def evaluator(task: str = None) -> Evaluator:
114
+ """
115
+ Utility factory method to build an [`Evaluator`].
116
+ Evaluators encapsulate a task and a default metric name. They leverage `pipeline` functionality from `transformers`
117
+ to simplify the evaluation of multiple combinations of models, datasets and metrics for a given task.
118
+ Args:
119
+ task (`str`):
120
+ The task defining which evaluator will be returned. Currently accepted tasks are:
121
+ - `"image-classification"`: will return a [`ImageClassificationEvaluator`].
122
+ - `"question-answering"`: will return a [`QuestionAnsweringEvaluator`].
123
+ - `"text-classification"` (alias `"sentiment-analysis"` available): will return a [`TextClassificationEvaluator`].
124
+ - `"token-classification"`: will return a [`TokenClassificationEvaluator`].
125
+ Returns:
126
+ [`Evaluator`]: An evaluator suitable for the task.
127
+ Examples:
128
+ ```python
129
+ >>> from evaluate import evaluator
130
+ >>> # Sentiment analysis evaluator
131
+ >>> evaluator("sentiment-analysis")
132
+ ```"""
133
+ if not TRANSFORMERS_AVAILABLE:
134
+ raise ImportError(
135
+ "If you want to use the `Evaluator` you need `transformers`. Run `pip install evaluate[transformers]`."
136
+ )
137
+ targeted_task = check_task(task)
138
+ evaluator_class = targeted_task["implementation"]
139
+ default_metric_name = targeted_task["default_metric_name"]
140
+ return evaluator_class(task=task, default_metric_name=default_metric_name)
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (5.01 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/audio_classification.cpython-312.pyc ADDED
Binary file (6.12 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/automatic_speech_recognition.cpython-312.pyc ADDED
Binary file (4.64 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/base.cpython-312.pyc ADDED
Binary file (23.6 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/image_classification.cpython-312.pyc ADDED
Binary file (5.07 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/question_answering.cpython-312.pyc ADDED
Binary file (10 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/text2text_generation.cpython-312.pyc ADDED
Binary file (9.07 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/text_classification.cpython-312.pyc ADDED
Binary file (6.9 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/text_generation.cpython-312.pyc ADDED
Binary file (3.02 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/token_classification.cpython-312.pyc ADDED
Binary file (11.9 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/__pycache__/utils.cpython-312.pyc ADDED
Binary file (4.41 kB). View file
 
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/audio_classification.py ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Evaluate Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from numbers import Number
16
+ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Tuple, Union
17
+
18
+ from datasets import Dataset
19
+ from typing_extensions import Literal
20
+
21
+ from ..module import EvaluationModule
22
+ from ..utils.file_utils import add_end_docstrings, add_start_docstrings
23
+ from .base import EVALUATOR_COMPUTE_RETURN_DOCSTRING, EVALUTOR_COMPUTE_START_DOCSTRING, Evaluator
24
+
25
+
26
+ if TYPE_CHECKING:
27
+ from transformers import FeatureExtractionMixin, Pipeline, PreTrainedModel, PreTrainedTokenizer, TFPreTrainedModel
28
+
29
+
30
+ TASK_DOCUMENTATION = r"""
31
+ Examples:
32
+
33
+ <Tip>
34
+
35
+ Remember that, in order to process audio files, you need ffmpeg installed (https://ffmpeg.org/download.html)
36
+
37
+ </Tip>
38
+
39
+ ```python
40
+ >>> from evaluate import evaluator
41
+ >>> from datasets import load_dataset
42
+
43
+ >>> task_evaluator = evaluator("audio-classification")
44
+ >>> data = load_dataset("superb", 'ks', split="test[:40]")
45
+ >>> results = task_evaluator.compute(
46
+ >>> model_or_pipeline=""superb/wav2vec2-base-superb-ks"",
47
+ >>> data=data,
48
+ >>> label_column="label",
49
+ >>> input_column="file",
50
+ >>> metric="accuracy",
51
+ >>> label_mapping={0: "yes", 1: "no", 2: "up", 3: "down"}
52
+ >>> )
53
+ ```
54
+
55
+ <Tip>
56
+
57
+ The evaluator supports raw audio data as well, in the form of a numpy array. However, be aware that calling
58
+ the audio column automatically decodes and resamples the audio files, which can be slow for large datasets.
59
+
60
+ </Tip>
61
+
62
+ ```python
63
+ >>> from evaluate import evaluator
64
+ >>> from datasets import load_dataset
65
+
66
+ >>> task_evaluator = evaluator("audio-classification")
67
+ >>> data = load_dataset("superb", 'ks', split="test[:40]")
68
+ >>> data = data.map(lambda example: {"audio": example["audio"]["array"]})
69
+ >>> results = task_evaluator.compute(
70
+ >>> model_or_pipeline=""superb/wav2vec2-base-superb-ks"",
71
+ >>> data=data,
72
+ >>> label_column="label",
73
+ >>> input_column="audio",
74
+ >>> metric="accuracy",
75
+ >>> label_mapping={0: "yes", 1: "no", 2: "up", 3: "down"}
76
+ >>> )
77
+ ```
78
+ """
79
+
80
+
81
+ class AudioClassificationEvaluator(Evaluator):
82
+ """
83
+ Audio classification evaluator.
84
+ This audio classification evaluator can currently be loaded from [`evaluator`] using the default task name
85
+ `audio-classification`.
86
+ Methods in this class assume a data format compatible with the [`transformers.AudioClassificationPipeline`].
87
+ """
88
+
89
+ PIPELINE_KWARGS = {}
90
+
91
+ def __init__(self, task="audio-classification", default_metric_name=None):
92
+ super().__init__(task, default_metric_name=default_metric_name)
93
+
94
+ def predictions_processor(self, predictions, label_mapping):
95
+ pred_label = [max(pred, key=lambda x: x["score"])["label"] for pred in predictions]
96
+ pred_label = [label_mapping[pred] if label_mapping is not None else pred for pred in pred_label]
97
+
98
+ return {"predictions": pred_label}
99
+
100
+ @add_start_docstrings(EVALUTOR_COMPUTE_START_DOCSTRING)
101
+ @add_end_docstrings(EVALUATOR_COMPUTE_RETURN_DOCSTRING, TASK_DOCUMENTATION)
102
+ def compute(
103
+ self,
104
+ model_or_pipeline: Union[
105
+ str, "Pipeline", Callable, "PreTrainedModel", "TFPreTrainedModel" # noqa: F821
106
+ ] = None,
107
+ data: Union[str, Dataset] = None,
108
+ subset: Optional[str] = None,
109
+ split: Optional[str] = None,
110
+ metric: Union[str, EvaluationModule] = None,
111
+ tokenizer: Optional[Union[str, "PreTrainedTokenizer"]] = None, # noqa: F821
112
+ feature_extractor: Optional[Union[str, "FeatureExtractionMixin"]] = None, # noqa: F821
113
+ strategy: Literal["simple", "bootstrap"] = "simple",
114
+ confidence_level: float = 0.95,
115
+ n_resamples: int = 9999,
116
+ device: int = None,
117
+ random_state: Optional[int] = None,
118
+ input_column: str = "file",
119
+ label_column: str = "label",
120
+ label_mapping: Optional[Dict[str, Number]] = None,
121
+ ) -> Tuple[Dict[str, float], Any]:
122
+
123
+ """
124
+ input_column (`str`, defaults to `"file"`):
125
+ The name of the column containing either the audio files or a raw waveform, represented as a numpy array, in the dataset specified by `data`.
126
+ label_column (`str`, defaults to `"label"`):
127
+ The name of the column containing the labels in the dataset specified by `data`.
128
+ label_mapping (`Dict[str, Number]`, *optional*, defaults to `None`):
129
+ We want to map class labels defined by the model in the pipeline to values consistent with those
130
+ defined in the `label_column` of the `data` dataset.
131
+ """
132
+
133
+ result = super().compute(
134
+ model_or_pipeline=model_or_pipeline,
135
+ data=data,
136
+ subset=subset,
137
+ split=split,
138
+ metric=metric,
139
+ tokenizer=tokenizer,
140
+ feature_extractor=feature_extractor,
141
+ strategy=strategy,
142
+ confidence_level=confidence_level,
143
+ n_resamples=n_resamples,
144
+ device=device,
145
+ random_state=random_state,
146
+ input_column=input_column,
147
+ label_column=label_column,
148
+ label_mapping=label_mapping,
149
+ )
150
+
151
+ return result
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/automatic_speech_recognition.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Evaluate Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Tuple, Union
16
+
17
+ from datasets import Dataset
18
+ from typing_extensions import Literal
19
+
20
+ from ..module import EvaluationModule
21
+ from ..utils.file_utils import add_end_docstrings, add_start_docstrings
22
+ from .base import EVALUATOR_COMPUTE_RETURN_DOCSTRING, EVALUTOR_COMPUTE_START_DOCSTRING, Evaluator
23
+
24
+
25
+ if TYPE_CHECKING:
26
+ from transformers import Pipeline, PreTrainedModel, PreTrainedTokenizer, TFPreTrainedModel
27
+
28
+
29
+ TASK_DOCUMENTATION = r"""
30
+ Examples:
31
+ ```python
32
+ >>> from evaluate import evaluator
33
+ >>> from datasets import load_dataset
34
+ >>> task_evaluator = evaluator("automatic-speech-recognition")
35
+ >>> data = load_dataset("mozilla-foundation/common_voice_11_0", "en", split="validation[:40]")
36
+ >>> results = task_evaluator.compute(
37
+ >>> model_or_pipeline="https://huggingface.co/openai/whisper-tiny.en",
38
+ >>> data=data,
39
+ >>> input_column="path",
40
+ >>> label_column="sentence",
41
+ >>> metric="wer",
42
+ >>> )
43
+ ```
44
+ """
45
+
46
+
47
+ class AutomaticSpeechRecognitionEvaluator(Evaluator):
48
+ """
49
+ Automatic speech recognition evaluator.
50
+ This automatic speech recognition evaluator can currently be loaded from [`evaluator`] using the default task name
51
+ `automatic-speech-recognition`.
52
+ Methods in this class assume a data format compatible with the [`AutomaticSpeechRecognitionPipeline`].
53
+ """
54
+
55
+ PIPELINE_KWARGS = {"truncation": True}
56
+
57
+ def __init__(self, task="automatic-speech-recognition", default_metric_name=None):
58
+ super().__init__(task, default_metric_name=default_metric_name)
59
+
60
+ def predictions_processor(self, predictions, label_mapping):
61
+ return {"predictions": [pred["text"] for pred in predictions]}
62
+
63
+ @add_start_docstrings(EVALUTOR_COMPUTE_START_DOCSTRING)
64
+ @add_end_docstrings(EVALUATOR_COMPUTE_RETURN_DOCSTRING, TASK_DOCUMENTATION)
65
+ def compute(
66
+ self,
67
+ model_or_pipeline: Union[
68
+ str, "Pipeline", Callable, "PreTrainedModel", "TFPreTrainedModel" # noqa: F821
69
+ ] = None,
70
+ data: Union[str, Dataset] = None,
71
+ subset: Optional[str] = None,
72
+ split: Optional[str] = None,
73
+ metric: Union[str, EvaluationModule] = None,
74
+ tokenizer: Optional[Union[str, "PreTrainedTokenizer"]] = None, # noqa: F821
75
+ strategy: Literal["simple", "bootstrap"] = "simple",
76
+ confidence_level: float = 0.95,
77
+ n_resamples: int = 9999,
78
+ device: int = None,
79
+ random_state: Optional[int] = None,
80
+ input_column: str = "path",
81
+ label_column: str = "sentence",
82
+ generation_kwargs: dict = None,
83
+ ) -> Tuple[Dict[str, float], Any]:
84
+ """
85
+ input_column (`str`, defaults to `"path"`):
86
+ the name of the column containing the input audio path in the dataset specified by `data`.
87
+ label_column (`str`, defaults to `"sentence"`):
88
+ the name of the column containing the labels in the dataset specified by `data`.
89
+ generation_kwargs (`Dict`, *optional*, defaults to `None`):
90
+ The generation kwargs are passed to the pipeline and set the text generation strategy.
91
+ """
92
+
93
+ if generation_kwargs is not None:
94
+ self.PIPELINE_KWARGS.update(generation_kwargs)
95
+
96
+ result = super().compute(
97
+ model_or_pipeline=model_or_pipeline,
98
+ data=data,
99
+ subset=subset,
100
+ split=split,
101
+ metric=metric,
102
+ tokenizer=tokenizer,
103
+ strategy=strategy,
104
+ confidence_level=confidence_level,
105
+ n_resamples=n_resamples,
106
+ device=device,
107
+ random_state=random_state,
108
+ input_column=input_column,
109
+ label_column=label_column,
110
+ )
111
+
112
+ return result
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/base.py ADDED
@@ -0,0 +1,544 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Datasets Authors and the TensorFlow Datasets Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from abc import ABC, abstractmethod
16
+ from numbers import Number
17
+ from typing import Any, Callable, Dict, List, Optional, Union
18
+
19
+ # Lint as: python3
20
+ from datasets import Dataset, load_dataset
21
+
22
+ from evaluate.evaluator.utils import choose_split
23
+
24
+
25
+ try:
26
+ from scipy.stats import bootstrap
27
+
28
+ SCIPY_AVAILABLE = True
29
+ except ImportError:
30
+ SCIPY_AVAILABLE = False
31
+
32
+ try:
33
+ import transformers
34
+ from transformers import Pipeline, pipeline
35
+
36
+ TRANSFORMERS_AVAILABLE = True
37
+ except ImportError:
38
+ TRANSFORMERS_AVAILABLE = False
39
+
40
+ from time import perf_counter
41
+
42
+ from typing_extensions import Literal
43
+
44
+ from ..loading import load
45
+ from ..module import EvaluationModule
46
+ from ..utils.logging import get_logger
47
+ from .utils import DatasetColumn
48
+
49
+
50
+ logger = get_logger(__name__)
51
+
52
+
53
+ EVALUTOR_COMPUTE_START_DOCSTRING = r"""
54
+ Compute the metric for a given pipeline and dataset combination.
55
+ Args:
56
+ model_or_pipeline (`str` or `Pipeline` or `Callable` or `PreTrainedModel` or `TFPreTrainedModel`, defaults to `None`):
57
+ If the argument in not specified, we initialize the default pipeline for the task (in this case
58
+ `text-classification` or its alias - `sentiment-analysis`). If the argument is of the type `str` or
59
+ is a model instance, we use it to initialize a new `Pipeline` with the given model. Otherwise we assume the
60
+ argument specifies a pre-initialized pipeline.
61
+ data (`str` or `Dataset`, defaults to `None`):
62
+ Specifies the dataset we will run evaluation on. If it is of type `str`, we treat it as the dataset
63
+ name, and load it. Otherwise we assume it represents a pre-loaded dataset.
64
+ subset (`str`, defaults to `None`):
65
+ Defines which dataset subset to load. If `None` is passed the default subset is loaded.
66
+ split (`str`, defaults to `None`):
67
+ Defines which dataset split to load. If `None` is passed, infers based on the `choose_split` function.
68
+ metric (`str` or `EvaluationModule`, defaults to `None`):
69
+ Specifies the metric we use in evaluator. If it is of type `str`, we treat it as the metric name, and
70
+ load it. Otherwise we assume it represents a pre-loaded metric.
71
+ tokenizer (`str` or `PreTrainedTokenizer`, *optional*, defaults to `None`):
72
+ Argument can be used to overwrite a default tokenizer if `model_or_pipeline` represents a model for
73
+ which we build a pipeline. If `model_or_pipeline` is `None` or a pre-initialized pipeline, we ignore
74
+ this argument.
75
+ strategy (`Literal["simple", "bootstrap"]`, defaults to "simple"):
76
+ specifies the evaluation strategy. Possible values are:
77
+ - `"simple"` - we evaluate the metric and return the scores.
78
+ - `"bootstrap"` - on top of computing the metric scores, we calculate the confidence interval for each
79
+ of the returned metric keys, using `scipy`'s `bootstrap` method
80
+ https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.bootstrap.html.
81
+ confidence_level (`float`, defaults to `0.95`):
82
+ The `confidence_level` value passed to `bootstrap` if `"bootstrap"` strategy is chosen.
83
+ n_resamples (`int`, defaults to `9999`):
84
+ The `n_resamples` value passed to `bootstrap` if `"bootstrap"` strategy is chosen.
85
+ device (`int`, defaults to `None`):
86
+ Device ordinal for CPU/GPU support of the pipeline. Setting this to -1 will leverage CPU, a positive
87
+ integer will run the model on the associated CUDA device ID. If `None` is provided it will be inferred and
88
+ CUDA:0 used if available, CPU otherwise.
89
+ random_state (`int`, *optional*, defaults to `None`):
90
+ The `random_state` value passed to `bootstrap` if `"bootstrap"` strategy is chosen. Useful for
91
+ debugging.
92
+ """
93
+
94
+ EVALUATOR_COMPUTE_RETURN_DOCSTRING = r"""
95
+ Return:
96
+ A `Dict`. The keys represent metric keys calculated for the `metric` spefied in function arguments. For the
97
+ `"simple"` strategy, the value is the metric score. For the `"bootstrap"` strategy, the value is a `Dict`
98
+ containing the score, the confidence interval and the standard error calculated for each metric key.
99
+ """
100
+
101
+
102
+ class Evaluator(ABC):
103
+ """
104
+ The [`Evaluator`] class is the class from which all evaluators inherit. Refer to this class for methods shared across
105
+ different evaluators.
106
+ Base class implementing evaluator operations.
107
+ """
108
+
109
+ PIPELINE_KWARGS = {}
110
+ METRIC_KWARGS = {}
111
+
112
+ def __init__(self, task: str, default_metric_name: str = None):
113
+ if not TRANSFORMERS_AVAILABLE:
114
+ raise ImportError(
115
+ "If you want to use the `Evaluator` you need `transformers`. Run `pip install evaluate[evaluator]`."
116
+ )
117
+ if not SCIPY_AVAILABLE:
118
+ raise ImportError(
119
+ "If you want to use the `Evaluator` you need `scipy>=1.7.1`. Run `pip install evaluate[evaluator]`."
120
+ )
121
+ self.task = task
122
+ self.default_metric_name = default_metric_name
123
+
124
+ @staticmethod
125
+ def _compute_confidence_interval(
126
+ metric,
127
+ metric_inputs,
128
+ metric_keys: List[str],
129
+ confidence_level: float = 0.95,
130
+ n_resamples: int = 9999,
131
+ random_state: Optional[int] = None,
132
+ ) -> Dict[str, Any]:
133
+ """
134
+ A utility function enabling the confidence interval calculation for metrics computed
135
+ by the evaluator based on `scipy`'s `bootstrap` method.
136
+ """
137
+
138
+ # bootstrap only works with functions that use args and no kwargs
139
+ def build_args_metric(metric, key, **kwargs):
140
+ def args_metric(*args):
141
+ return metric.compute(**{k: v for k, v in zip(kwargs.keys(), args)})[key]
142
+
143
+ return args_metric
144
+
145
+ bootstrap_dict = {}
146
+ for key in metric_keys:
147
+ bs = bootstrap(
148
+ data=list(metric_inputs.values()),
149
+ statistic=build_args_metric(metric, key, **metric_inputs),
150
+ paired=True,
151
+ vectorized=False,
152
+ confidence_level=confidence_level,
153
+ n_resamples=n_resamples,
154
+ random_state=random_state,
155
+ )
156
+ bootstrap_dict[key] = {
157
+ "confidence_interval": (bs.confidence_interval.low, bs.confidence_interval.high),
158
+ "standard_error": bs.standard_error,
159
+ }
160
+ return bootstrap_dict
161
+
162
+ @staticmethod
163
+ def _compute_time_perf(start_time: float, end_time: float, num_samples: int) -> Dict[str, Any]:
164
+ """
165
+ A utility function computing time performance metrics:
166
+ - `total_time_in_seconds` - pipeline inference runtime for the evaluation data in seconds,
167
+ - `samples_per_second` - pipeline throughput in the number of samples per second.
168
+ - `latency_in_seconds` - pipeline inference runtime for the evaluation data in seconds per sample,
169
+
170
+ """
171
+ latency = end_time - start_time
172
+ throughput = num_samples / latency
173
+ latency_sample = 1.0 / throughput
174
+
175
+ return {
176
+ "total_time_in_seconds": latency,
177
+ "samples_per_second": throughput,
178
+ "latency_in_seconds": latency_sample,
179
+ }
180
+
181
+ @staticmethod
182
+ def _infer_device() -> int:
183
+ """Helper function to check if GPU or CPU is available for inference."""
184
+ # try infer with torch first
185
+ try:
186
+ import torch
187
+
188
+ if torch.cuda.is_available():
189
+ device = 0 # first GPU
190
+ else:
191
+ device = -1 # CPU
192
+ except ImportError:
193
+ # if not available try TF
194
+ try:
195
+ import tensorflow as tf
196
+
197
+ if len(tf.config.list_physical_devices("GPU")) > 0:
198
+ device = 0 # first GPU
199
+ else:
200
+ device = -1 # CPU
201
+ except ImportError:
202
+ device = -1
203
+
204
+ if device == -1:
205
+ logger.info("No GPU found. The default device for pipeline inference is set to CPU.")
206
+ else:
207
+ logger.info("GPU found. The default device for pipeline inference is set to GPU (CUDA:0).")
208
+
209
+ return device
210
+
211
+ @abstractmethod
212
+ def predictions_processor(self, *args, **kwargs):
213
+ """
214
+ A core method of the `Evaluator` class, which processes the pipeline outputs for compatibility with the metric.
215
+ """
216
+ raise NotImplementedError()
217
+
218
+ def compute(
219
+ self,
220
+ model_or_pipeline: Union[
221
+ str, "Pipeline", Callable, "PreTrainedModel", "TFPreTrainedModel" # noqa: F821
222
+ ] = None,
223
+ data: Union[str, Dataset] = None,
224
+ subset: Optional[str] = None,
225
+ split: Optional[str] = None,
226
+ metric: Union[str, EvaluationModule] = None,
227
+ tokenizer: Optional[Union[str, "PreTrainedTokenizer"]] = None, # noqa: F821
228
+ feature_extractor: Optional[Union[str, "FeatureExtractionMixin"]] = None, # noqa: F821
229
+ strategy: Literal["simple", "bootstrap"] = "simple",
230
+ confidence_level: float = 0.95,
231
+ n_resamples: int = 9999,
232
+ device: int = None,
233
+ random_state: Optional[int] = None,
234
+ input_column: str = "text",
235
+ label_column: str = "label",
236
+ label_mapping: Optional[Dict[str, Number]] = None,
237
+ ) -> Dict[str, float]:
238
+
239
+ result = {}
240
+
241
+ self.check_for_mismatch_in_device_setup(device, model_or_pipeline)
242
+
243
+ # Prepare inputs
244
+ data = self.load_data(data=data, subset=subset, split=split)
245
+ metric_inputs, pipe_inputs = self.prepare_data(data=data, input_column=input_column, label_column=label_column)
246
+ pipe = self.prepare_pipeline(
247
+ model_or_pipeline=model_or_pipeline,
248
+ tokenizer=tokenizer,
249
+ feature_extractor=feature_extractor,
250
+ device=device,
251
+ )
252
+ metric = self.prepare_metric(metric)
253
+
254
+ # Compute predictions
255
+ predictions, perf_results = self.call_pipeline(pipe, pipe_inputs)
256
+ predictions = self.predictions_processor(predictions, label_mapping)
257
+
258
+ metric_inputs.update(predictions)
259
+
260
+ # Compute metrics from references and predictions
261
+ metric_results = self.compute_metric(
262
+ metric=metric,
263
+ metric_inputs=metric_inputs,
264
+ strategy=strategy,
265
+ confidence_level=confidence_level,
266
+ n_resamples=n_resamples,
267
+ random_state=random_state,
268
+ )
269
+
270
+ # TODO: To clarify why `wer` and `cer` return float
271
+ # even though metric.compute contract says that it
272
+ # returns Optional[dict].
273
+ if type(metric_results) is float:
274
+ metric_results = {metric.name: metric_results}
275
+
276
+ result.update(metric_results)
277
+ result.update(perf_results)
278
+
279
+ return result
280
+
281
+ @staticmethod
282
+ def check_for_mismatch_in_device_setup(device, model_or_pipeline):
283
+ if device is not None and device != -1 and isinstance(model_or_pipeline, Pipeline):
284
+ if model_or_pipeline.device.type == "cpu":
285
+ raise ValueError(
286
+ "The value of the `device` kwarg passed to `compute` suggests that this pipe should be run on an "
287
+ "accelerator, but the pipe was instantiated on CPU. Pass `device` to the pipeline during "
288
+ "initialization to use an accelerator, or pass `device=None` to `compute`. "
289
+ )
290
+ elif device != model_or_pipeline.device.index:
291
+ raise ValueError(
292
+ f"This pipeline was instantiated on device {model_or_pipeline.device.index} but device={device} was passed to `compute`."
293
+ )
294
+
295
+ def check_required_columns(self, data: Union[str, Dataset], columns_names: Dict[str, str]):
296
+ """
297
+ Ensure the columns required for the evaluation are present in the dataset.
298
+
299
+ Args:
300
+ data (`str` or [`Dataset`]):
301
+ Specifies the dataset we will run evaluation on.
302
+ columns_names (`List[str]`):
303
+ List of column names to check in the dataset. The keys are the arguments to the [`evaluate.EvaluationModule.compute`] method,
304
+ while the values are the column names to check.
305
+
306
+ Example:
307
+
308
+ ```py
309
+ >>> from datasets import load_dataset
310
+ >>> from evaluate import evaluator
311
+ >>> data = load_dataset("rotten_tomatoes', split="train")
312
+ >>> evaluator.check_required_columns(data, {"input_column": "text", "label_column": "label"})
313
+ ```
314
+ """
315
+ for input_name, column_name in columns_names.items():
316
+ if column_name not in data.column_names:
317
+ raise ValueError(
318
+ f"Invalid `{input_name}` {column_name} specified. The dataset contains the following columns: {data.column_names}."
319
+ )
320
+
321
+ @staticmethod
322
+ def get_dataset_split(data, subset=None, split=None):
323
+ """
324
+ Infers which split to use if `None` is given.
325
+
326
+ Args:
327
+ data (`str`):
328
+ Name of dataset.
329
+ subset (`str`):
330
+ Name of config for datasets with multiple configurations (e.g. 'glue/cola').
331
+ split (`str`, defaults to `None`):
332
+ Split to use.
333
+ Returns:
334
+ `split`: `str` containing which split to use
335
+
336
+ Example:
337
+
338
+ ```py
339
+ >>> from evaluate import evaluator
340
+ >>> evaluator("text-classification").get_dataset_split(data="rotten_tomatoes")
341
+ WARNING:evaluate.evaluator.base:Dataset split not defined! Automatically evaluating with split: TEST
342
+ 'test'
343
+ ```
344
+ """
345
+ if split is None:
346
+ split = choose_split(data, subset)
347
+ logger.warning(f"Dataset split not defined! Automatically evaluating with split: {split.upper()}")
348
+ return split
349
+
350
+ def load_data(self, data: Union[str, Dataset], subset: str = None, split: str = None):
351
+ """
352
+ Load dataset with given subset and split.
353
+ Args:
354
+ data ([`Dataset`] or `str`, defaults to `None`):
355
+ Specifies the dataset we will run evaluation on. If it is of
356
+ type `str`, we treat it as the dataset name, and load it. Otherwise we assume it represents a pre-loaded dataset.
357
+ subset (`str`, defaults to `None`):
358
+ Specifies dataset subset to be passed to `name` in `load_dataset`. To be
359
+ used with datasets with several configurations (e.g. glue/sst2).
360
+ split (`str`, defaults to `None`):
361
+ User-defined dataset split by name (e.g. train, validation, test). Supports slice-split (`test[:n]`).
362
+ If not defined and data is a `str` type, will automatically select the best one via `choose_split()`.
363
+ Returns:
364
+ data ([`Dataset`]): Loaded dataset which will be used for evaluation.
365
+
366
+ Example:
367
+
368
+ ```py
369
+ >>> from evaluate import evaluator
370
+ >>> evaluator("text-classification").load_data(data="rotten_tomatoes", split="train")
371
+ Dataset({
372
+ features: ['text', 'label'],
373
+ num_rows: 8530
374
+ })
375
+ ```
376
+ """
377
+ if isinstance(data, str):
378
+ split = self.get_dataset_split(data, subset, split)
379
+ data = load_dataset(data, name=subset, split=split)
380
+ return data
381
+ elif isinstance(data, Dataset):
382
+ if split is not None or subset is not None:
383
+ logger.warning("`data` is a preloaded Dataset! Ignoring `subset` and `split`.")
384
+ return data
385
+ else:
386
+ raise ValueError(
387
+ "Please specify a valid `data` object - either a `str` with a name or a `Dataset` object."
388
+ )
389
+
390
+ def prepare_data(self, data: Dataset, input_column: str, label_column: str, *args, **kwargs):
391
+ """
392
+ Prepare data.
393
+
394
+ Args:
395
+ data ([`Dataset`]):
396
+ Specifies the dataset we will run evaluation on.
397
+ input_column (`str`, defaults to `"text"`):
398
+ The name of the column containing the text feature in the dataset specified by `data`.
399
+ second_input_column(`str`, *optional*):
400
+ The name of the column containing the second text feature if there is one. Otherwise, set to `None`.
401
+ label_column (`str`, defaults to `"label"`):
402
+ The name of the column containing the labels in the dataset specified by `data`.
403
+ Returns:
404
+ `dict`: metric inputs.
405
+ `list`: pipeline inputs.
406
+
407
+ Example:
408
+
409
+ ```py
410
+ >>> from evaluate import evaluator
411
+ >>> from datasets import load_dataset
412
+
413
+ >>> ds = load_dataset("rotten_tomatoes", split="train")
414
+ >>> evaluator("text-classification").prepare_data(ds, input_column="text", second_input_column=None, label_column="label")
415
+ ```
416
+ """
417
+
418
+ self.check_required_columns(data, {"input_column": input_column, "label_column": label_column})
419
+
420
+ return {"references": data[label_column]}, DatasetColumn(data, input_column)
421
+
422
+ def prepare_pipeline(
423
+ self,
424
+ model_or_pipeline: Union[str, "Pipeline", Callable, "PreTrainedModel", "TFPreTrainedModel"], # noqa: F821
425
+ tokenizer: Union["PreTrainedTokenizerBase", "FeatureExtractionMixin"] = None, # noqa: F821
426
+ feature_extractor: Union["PreTrainedTokenizerBase", "FeatureExtractionMixin"] = None, # noqa: F821
427
+ device: int = None,
428
+ ):
429
+ """
430
+ Prepare pipeline.
431
+
432
+ Args:
433
+ model_or_pipeline (`str` or [`~transformers.Pipeline`] or `Callable` or [`~transformers.PreTrainedModel`] or [`~transformers.TFPreTrainedModel`], defaults to `None`):
434
+ If the argument in not specified, we initialize the default pipeline for the task. If the argument is of the type `str` or
435
+ is a model instance, we use it to initialize a new [`~transformers.Pipeline`] with the given model. Otherwise we assume the
436
+ argument specifies a pre-initialized pipeline.
437
+ preprocessor ([`~transformers.PreTrainedTokenizerBase`] or [`~transformers.FeatureExtractionMixin`], *optional*, defaults to `None`):
438
+ Argument can be used to overwrite a default preprocessor if `model_or_pipeline` represents a model for
439
+ which we build a pipeline. If `model_or_pipeline` is `None` or a pre-initialized pipeline, we ignore
440
+ this argument.
441
+ Returns:
442
+ The initialized pipeline.
443
+
444
+ Example:
445
+
446
+ ```py
447
+ >>> from evaluate import evaluator
448
+ >>> evaluator("text-classification").prepare_pipeline(model_or_pipeline="distilbert-base-uncased")
449
+ ```
450
+ """
451
+
452
+ if device is None:
453
+ device = self._infer_device()
454
+
455
+ if (
456
+ isinstance(model_or_pipeline, str)
457
+ or isinstance(model_or_pipeline, transformers.PreTrainedModel)
458
+ or isinstance(model_or_pipeline, transformers.TFPreTrainedModel)
459
+ ):
460
+ pipe = pipeline(
461
+ self.task,
462
+ model=model_or_pipeline,
463
+ tokenizer=tokenizer,
464
+ feature_extractor=feature_extractor,
465
+ device=device,
466
+ )
467
+ else:
468
+ if model_or_pipeline is None:
469
+ pipe = pipeline(self.task, device=device)
470
+ else:
471
+ pipe = model_or_pipeline
472
+ if tokenizer is not None and feature_extractor is not None:
473
+ logger.warning("Ignoring the value of the preprocessor argument (`tokenizer` or `feature_extractor`).")
474
+ if (pipe.task != self.task) and not (self.task == "translation" and pipe.task.startswith("translation")):
475
+ raise ValueError(
476
+ f"Incompatible `model_or_pipeline`. Please specify `model_or_pipeline` compatible with the `{self.task}` task."
477
+ )
478
+ return pipe
479
+
480
+ def prepare_metric(self, metric: Union[str, EvaluationModule]):
481
+ """
482
+ Prepare metric.
483
+
484
+ Args:
485
+ metric (`str` or [`EvaluationModule`], defaults to `None`):
486
+ Specifies the metric we use in evaluator. If it is of type `str`, we treat it as the metric name, and
487
+ load it. Otherwise we assume it represents a pre-loaded metric.
488
+
489
+ Returns:
490
+ The loaded metric.
491
+
492
+ Example:
493
+
494
+ ```py
495
+ >>> from evaluate import evaluator
496
+ >>> evaluator("text-classification").prepare_metric("accuracy")
497
+ ```
498
+ """
499
+ # Prepare metric.
500
+ if metric is None:
501
+ if self.default_metric_name is None:
502
+ raise ValueError(
503
+ "`Evaluator` doesn't specify a default metric. Please specify a valid `metric` argument."
504
+ )
505
+ metric = load(self.default_metric_name)
506
+ elif isinstance(metric, str):
507
+ metric = load(metric)
508
+
509
+ return metric
510
+
511
+ def call_pipeline(self, pipe, *args, **kwargs):
512
+ start_time = perf_counter()
513
+ pipe_output = pipe(*args, **kwargs, **self.PIPELINE_KWARGS)
514
+ end_time = perf_counter()
515
+ return pipe_output, self._compute_time_perf(start_time, end_time, len(pipe_output))
516
+
517
+ def compute_metric(
518
+ self,
519
+ metric: EvaluationModule,
520
+ metric_inputs: Dict,
521
+ strategy: Literal["simple", "bootstrap"] = "simple",
522
+ confidence_level: float = 0.95,
523
+ n_resamples: int = 9999,
524
+ random_state: Optional[int] = None,
525
+ ):
526
+ """Compute and return metrics."""
527
+ result = metric.compute(**metric_inputs, **self.METRIC_KWARGS)
528
+
529
+ if strategy == "bootstrap":
530
+ metric_keys = result.keys()
531
+ bootstrap_dict = self._compute_confidence_interval(
532
+ metric,
533
+ metric_inputs,
534
+ metric_keys,
535
+ confidence_level,
536
+ n_resamples,
537
+ random_state,
538
+ )
539
+ for key in metric_keys:
540
+ bootstrap_dict[key]["score"] = result[key]
541
+
542
+ return bootstrap_dict
543
+
544
+ return result
Prism/LLaDA/LLaDA_Prism/.venv/lib/python3.12/site-packages/evaluate/evaluator/image_classification.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 The HuggingFace Evaluate Authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from numbers import Number
16
+ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Tuple, Union
17
+
18
+ from datasets import Dataset
19
+ from typing_extensions import Literal
20
+
21
+ from ..module import EvaluationModule
22
+ from ..utils.file_utils import add_end_docstrings, add_start_docstrings
23
+ from .base import EVALUATOR_COMPUTE_RETURN_DOCSTRING, EVALUTOR_COMPUTE_START_DOCSTRING, Evaluator
24
+
25
+
26
+ if TYPE_CHECKING:
27
+ from transformers import FeatureExtractionMixin, Pipeline, PreTrainedModel, PreTrainedTokenizer, TFPreTrainedModel
28
+
29
+
30
+ TASK_DOCUMENTATION = r"""
31
+ Examples:
32
+ ```python
33
+ >>> from evaluate import evaluator
34
+ >>> from datasets import load_dataset
35
+ >>> task_evaluator = evaluator("image-classification")
36
+ >>> data = load_dataset("beans", split="test[:40]")
37
+ >>> results = task_evaluator.compute(
38
+ >>> model_or_pipeline="nateraw/vit-base-beans",
39
+ >>> data=data,
40
+ >>> label_column="labels",
41
+ >>> metric="accuracy",
42
+ >>> label_mapping={'angular_leaf_spot': 0, 'bean_rust': 1, 'healthy': 2},
43
+ >>> strategy="bootstrap"
44
+ >>> )
45
+ ```
46
+ """
47
+
48
+
49
+ class ImageClassificationEvaluator(Evaluator):
50
+ """
51
+ Image classification evaluator.
52
+ This image classification evaluator can currently be loaded from [`evaluator`] using the default task name
53
+ `image-classification`.
54
+ Methods in this class assume a data format compatible with the [`ImageClassificationPipeline`].
55
+ """
56
+
57
+ PIPELINE_KWARGS = {}
58
+
59
+ def __init__(self, task="image-classification", default_metric_name=None):
60
+ super().__init__(task, default_metric_name=default_metric_name)
61
+
62
+ def predictions_processor(self, predictions, label_mapping):
63
+ pred_label = [max(pred, key=lambda x: x["score"])["label"] for pred in predictions]
64
+ pred_label = [label_mapping[pred] if label_mapping is not None else pred for pred in pred_label]
65
+
66
+ return {"predictions": pred_label}
67
+
68
+ @add_start_docstrings(EVALUTOR_COMPUTE_START_DOCSTRING)
69
+ @add_end_docstrings(EVALUATOR_COMPUTE_RETURN_DOCSTRING, TASK_DOCUMENTATION)
70
+ def compute(
71
+ self,
72
+ model_or_pipeline: Union[
73
+ str, "Pipeline", Callable, "PreTrainedModel", "TFPreTrainedModel" # noqa: F821
74
+ ] = None,
75
+ data: Union[str, Dataset] = None,
76
+ subset: Optional[str] = None,
77
+ split: Optional[str] = None,
78
+ metric: Union[str, EvaluationModule] = None,
79
+ tokenizer: Optional[Union[str, "PreTrainedTokenizer"]] = None, # noqa: F821
80
+ feature_extractor: Optional[Union[str, "FeatureExtractionMixin"]] = None, # noqa: F821
81
+ strategy: Literal["simple", "bootstrap"] = "simple",
82
+ confidence_level: float = 0.95,
83
+ n_resamples: int = 9999,
84
+ device: int = None,
85
+ random_state: Optional[int] = None,
86
+ input_column: str = "image",
87
+ label_column: str = "label",
88
+ label_mapping: Optional[Dict[str, Number]] = None,
89
+ ) -> Tuple[Dict[str, float], Any]:
90
+
91
+ """
92
+ input_column (`str`, defaults to `"image"`):
93
+ The name of the column containing the images as PIL ImageFile in the dataset specified by `data`.
94
+ label_column (`str`, defaults to `"label"`):
95
+ The name of the column containing the labels in the dataset specified by `data`.
96
+ label_mapping (`Dict[str, Number]`, *optional*, defaults to `None`):
97
+ We want to map class labels defined by the model in the pipeline to values consistent with those
98
+ defined in the `label_column` of the `data` dataset.
99
+ """
100
+
101
+ result = super().compute(
102
+ model_or_pipeline=model_or_pipeline,
103
+ data=data,
104
+ subset=subset,
105
+ split=split,
106
+ metric=metric,
107
+ tokenizer=tokenizer,
108
+ feature_extractor=feature_extractor,
109
+ strategy=strategy,
110
+ confidence_level=confidence_level,
111
+ n_resamples=n_resamples,
112
+ device=device,
113
+ random_state=random_state,
114
+ input_column=input_column,
115
+ label_column=label_column,
116
+ label_mapping=label_mapping,
117
+ )
118
+
119
+ return result