edsl 0.1.53__py3-none-any.whl → 0.1.54__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,7 +51,7 @@ def _parse_type_string(type_str: str) -> Any:
51
51
  return List[Any]
52
52
  elif type_str.startswith("list["):
53
53
  # e.g. "list[str]" or "list[int]" etc.
54
- inner = type_str[len("list["):-1].strip()
54
+ inner = type_str[len("list[") : -1].strip()
55
55
  return List[_parse_type_string(inner)]
56
56
  # If none matched, return a very permissive type or raise an error
57
57
  return Any
@@ -74,15 +74,16 @@ def create_dict_response(
74
74
  # 1) Build the 'answer' submodel fields
75
75
  # Each key is required (using `...`), with the associated type from value_types.
76
76
  field_definitions = {}
77
+ if len(value_types) == 0:
78
+ value_types = ["str"] * len(answer_keys) # Default to str if no types provided
79
+
77
80
  for key, t_str in zip(answer_keys, value_types):
78
81
  python_type = _parse_type_string(t_str)
79
82
  field_definitions[key] = (python_type, Field(...))
80
83
 
81
84
  # Use Pydantic's create_model to construct an "AnswerSubModel" with these fields
82
85
  AnswerSubModel = create_model(
83
- "AnswerSubModel",
84
- __base__=BaseModel,
85
- **field_definitions
86
+ "AnswerSubModel", __base__=BaseModel, **field_definitions
86
87
  )
87
88
 
88
89
  # 2) Define the top-level model with `answer` + optional `comment`
@@ -102,12 +103,12 @@ def create_dict_response(
102
103
  class DictResponseValidator(ResponseValidatorABC):
103
104
  """
104
105
  Validator for dictionary responses with specific keys and value types.
105
-
106
+
106
107
  This validator ensures that:
107
108
  1. All required keys are present in the answer
108
109
  2. Each value has the correct type as specified
109
110
  3. Extra keys are forbidden unless permissive=True
110
-
111
+
111
112
  Examples:
112
113
  >>> from edsl.questions import QuestionDict
113
114
  >>> q = QuestionDict(
@@ -119,7 +120,7 @@ class DictResponseValidator(ResponseValidatorABC):
119
120
  >>> validator = q.response_validator
120
121
  >>> result = validator.validate({
121
122
  ... "answer": {
122
- ... "name": "Pancakes",
123
+ ... "name": "Pancakes",
123
124
  ... "ingredients": ["flour", "milk", "eggs"],
124
125
  ... "steps": ["Mix", "Cook", "Serve"]
125
126
  ... }
@@ -127,12 +128,13 @@ class DictResponseValidator(ResponseValidatorABC):
127
128
  >>> sorted(result.keys())
128
129
  ['answer', 'comment', 'generated_tokens']
129
130
  """
131
+
130
132
  required_params = ["answer_keys", "permissive"]
131
133
 
132
134
  def fix(self, response, verbose=False):
133
135
  """
134
136
  Attempt to fix an invalid dictionary response.
135
-
137
+
136
138
  Examples:
137
139
  >>> # Set up validator with proper response model
138
140
  >>> from pydantic import BaseModel, create_model, Field
@@ -151,7 +153,7 @@ class DictResponseValidator(ResponseValidatorABC):
151
153
  ... permissive=False
152
154
  ... )
153
155
  >>> validator.value_types = ["str", "int"]
154
-
156
+
155
157
  # Fix dictionary with comment on same line
156
158
  >>> response = "{'name': 'john', 'age': 23} Here you go."
157
159
  >>> result = validator.fix(response)
@@ -159,13 +161,13 @@ class DictResponseValidator(ResponseValidatorABC):
159
161
  {'name': 'john', 'age': 23}
160
162
  >>> result['comment']
161
163
  'Here you go.'
162
-
164
+
163
165
  # Fix type conversion (string to int)
164
166
  >>> response = {"answer": {"name": "john", "age": "23"}}
165
167
  >>> result = validator.fix(response)
166
168
  >>> dict(result['answer']) # Convert to dict for consistent output
167
169
  {'name': 'john', 'age': 23}
168
-
170
+
169
171
  # Fix list from comma-separated string
170
172
  >>> AnswerModel2 = create_model('AnswerModel2', name=(str, ...), hobbies=(List[str], ...))
171
173
  >>> ResponseModel2 = create_model(
@@ -184,7 +186,7 @@ class DictResponseValidator(ResponseValidatorABC):
184
186
  >>> result = validator.fix(response)
185
187
  >>> dict(result['answer']) # Convert to dict for consistent output
186
188
  {'name': 'john', 'hobbies': ['reading', 'gaming', 'coding']}
187
-
189
+
188
190
  # Handle invalid input gracefully
189
191
  >>> response = "not a dictionary"
190
192
  >>> validator.fix(response)
@@ -194,14 +196,14 @@ class DictResponseValidator(ResponseValidatorABC):
194
196
  if isinstance(response, str):
195
197
  # Try to find where the dictionary ends and comment begins
196
198
  try:
197
- dict_match = re.match(r'(\{.*?\})(.*)', response.strip())
199
+ dict_match = re.match(r"(\{.*?\})(.*)", response.strip())
198
200
  if dict_match:
199
201
  dict_str, comment = dict_match.groups()
200
202
  try:
201
203
  answer_dict = ast.literal_eval(dict_str)
202
204
  response = {
203
205
  "answer": answer_dict,
204
- "comment": comment.strip() if comment.strip() else None
206
+ "comment": comment.strip() if comment.strip() else None,
205
207
  }
206
208
  except (ValueError, SyntaxError):
207
209
  pass
@@ -213,10 +215,10 @@ class DictResponseValidator(ResponseValidatorABC):
213
215
  if verbose:
214
216
  print("Cannot fix response: 'answer' field missing or not a dictionary")
215
217
  return response
216
-
218
+
217
219
  answer_dict = response["answer"]
218
220
  fixed_answer = {}
219
-
221
+
220
222
  # Try to convert values to expected types
221
223
  for key, type_str in zip(self.answer_keys, getattr(self, "value_types", [])):
222
224
  if key in answer_dict:
@@ -226,20 +228,24 @@ class DictResponseValidator(ResponseValidatorABC):
226
228
  try:
227
229
  fixed_answer[key] = int(value)
228
230
  if verbose:
229
- print(f"Converted '{key}' from {type(value).__name__} to int")
231
+ print(
232
+ f"Converted '{key}' from {type(value).__name__} to int"
233
+ )
230
234
  continue
231
235
  except (ValueError, TypeError):
232
236
  pass
233
-
237
+
234
238
  elif type_str == "float" and not isinstance(value, float):
235
239
  try:
236
240
  fixed_answer[key] = float(value)
237
241
  if verbose:
238
- print(f"Converted '{key}' from {type(value).__name__} to float")
242
+ print(
243
+ f"Converted '{key}' from {type(value).__name__} to float"
244
+ )
239
245
  continue
240
246
  except (ValueError, TypeError):
241
247
  pass
242
-
248
+
243
249
  elif type_str.startswith("list[") and not isinstance(value, list):
244
250
  # Try to convert string to list by splitting
245
251
  if isinstance(value, str):
@@ -248,22 +254,22 @@ class DictResponseValidator(ResponseValidatorABC):
248
254
  if verbose:
249
255
  print(f"Converted '{key}' from string to list: {items}")
250
256
  continue
251
-
257
+
252
258
  # If no conversion needed or possible, keep original
253
259
  fixed_answer[key] = value
254
-
260
+
255
261
  # Preserve any keys we didn't try to fix
256
262
  for key, value in answer_dict.items():
257
263
  if key not in fixed_answer:
258
264
  fixed_answer[key] = value
259
-
265
+
260
266
  # Return fixed response
261
267
  fixed_response = {
262
268
  "answer": fixed_answer,
263
269
  "comment": response.get("comment"),
264
- "generated_tokens": response.get("generated_tokens")
270
+ "generated_tokens": response.get("generated_tokens"),
265
271
  }
266
-
272
+
267
273
  try:
268
274
  # Validate the fixed answer
269
275
  self.response_model.model_validate(fixed_response)
@@ -281,12 +287,12 @@ class DictResponseValidator(ResponseValidatorABC):
281
287
  "answer": {
282
288
  "name": "Hot Chocolate",
283
289
  "num_ingredients": 5,
284
- "ingredients": ["milk", "cocoa", "sugar"]
290
+ "ingredients": ["milk", "cocoa", "sugar"],
285
291
  }
286
292
  },
287
293
  {
288
294
  "answer_keys": ["name", "num_ingredients", "ingredients"],
289
- "value_types": ["str", "int", "list[str]"]
295
+ "value_types": ["str", "int", "list[str]"],
290
296
  },
291
297
  )
292
298
  ]
@@ -300,7 +306,7 @@ class DictResponseValidator(ResponseValidatorABC):
300
306
  {"answer": {"ingredients": "milk"}}, # Should be a list
301
307
  {"answer_keys": ["ingredients"], "value_types": ["list[str]"]},
302
308
  "Key 'ingredients' should be a list, got str",
303
- )
309
+ ),
304
310
  ]
305
311
 
306
312
 
@@ -373,7 +379,9 @@ class QuestionDict(QuestionBase):
373
379
  raise QuestionCreationValidationError(
374
380
  "Length of value_types must match length of answer_keys."
375
381
  )
376
- if self.value_descriptions and len(self.value_descriptions) != len(self.answer_keys):
382
+ if self.value_descriptions and len(self.value_descriptions) != len(
383
+ self.answer_keys
384
+ ):
377
385
  raise QuestionCreationValidationError(
378
386
  "Length of value_descriptions must match length of answer_keys."
379
387
  )
@@ -386,7 +394,7 @@ class QuestionDict(QuestionBase):
386
394
  return create_dict_response(
387
395
  answer_keys=self.answer_keys,
388
396
  value_types=self.value_types or [],
389
- permissive=self.permissive
397
+ permissive=self.permissive,
390
398
  )
391
399
 
392
400
  def _get_default_answer(self) -> Dict[str, Any]:
@@ -397,7 +405,7 @@ class QuestionDict(QuestionBase):
397
405
  "title": "Sample Recipe",
398
406
  "ingredients": ["ingredient1", "ingredient2"],
399
407
  "num_ingredients": 2,
400
- "instructions": "Sample instructions"
408
+ "instructions": "Sample instructions",
401
409
  }
402
410
 
403
411
  answer = {}
@@ -405,7 +413,7 @@ class QuestionDict(QuestionBase):
405
413
  t_str = type_str.lower()
406
414
  if t_str.startswith("list["):
407
415
  # e.g. list[str], list[int], etc.
408
- inner = t_str[len("list["):-1].strip()
416
+ inner = t_str[len("list[") : -1].strip()
409
417
  if inner == "str":
410
418
  answer[key] = ["sample_string"]
411
419
  elif inner == "int":
@@ -445,7 +453,9 @@ class QuestionDict(QuestionBase):
445
453
  return f"Template {template_name} not found in {template_dir}."
446
454
 
447
455
  @staticmethod
448
- def _normalize_value_types(value_types: Optional[List[Union[str, type]]]) -> Optional[List[str]]:
456
+ def _normalize_value_types(
457
+ value_types: Optional[List[Union[str, type]]]
458
+ ) -> Optional[List[str]]:
449
459
  """
450
460
  Convert all value_types to string representations (e.g. "int", "list[str]", etc.).
451
461
  This logic is similar to your original approach but expanded to handle
@@ -486,7 +496,7 @@ class QuestionDict(QuestionBase):
486
496
  }
487
497
 
488
498
  @classmethod
489
- def from_dict(cls, data: dict) -> 'QuestionDict':
499
+ def from_dict(cls, data: dict) -> "QuestionDict":
490
500
  """Recreate from a dictionary."""
491
501
  return cls(
492
502
  question_name=data["question_name"],
@@ -500,7 +510,7 @@ class QuestionDict(QuestionBase):
500
510
 
501
511
  @classmethod
502
512
  @inject_exception
503
- def example(cls) -> 'QuestionDict':
513
+ def example(cls) -> "QuestionDict":
504
514
  """Return an example question."""
505
515
  return cls(
506
516
  question_name="example",
@@ -511,16 +521,13 @@ class QuestionDict(QuestionBase):
511
521
  "The title of the recipe.",
512
522
  "A list of ingredients.",
513
523
  "The number of ingredients.",
514
- "The instructions for making the recipe."
524
+ "The instructions for making the recipe.",
515
525
  ],
516
526
  )
517
527
 
518
528
  def _simulate_answer(self) -> dict:
519
529
  """Simulate an answer for the question."""
520
- return {
521
- "answer": self._get_default_answer(),
522
- "comment": None
523
- }
530
+ return {"answer": self._get_default_answer(), "comment": None}
524
531
 
525
532
 
526
533
  if __name__ == "__main__":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.53
3
+ Version: 0.1.54
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
@@ -83,6 +83,7 @@ results = q.run()
83
83
  results.select("example")
84
84
  ```
85
85
 
86
+
86
87
  > | answer.example |
87
88
  > |-----------------|
88
89
  > | Good |
@@ -1,5 +1,5 @@
1
1
  edsl/__init__.py,sha256=SXi_Zm4kf6H2WW_YeTuF6zRNZEWKzpKa7NRXUzn2Ty4,4593
2
- edsl/__version__.py,sha256=FdQ5_-vfyHXSNAuzQXtxxDH2WjNJ3g581mH_zvly6Xo,23
2
+ edsl/__version__.py,sha256=0U9S9zRz7MduvARyiWFUbfYZNKDf9XCo9-1NqTcx3CU,23
3
3
  edsl/agents/__init__.py,sha256=AyhfXjygRHT1Pd9w16lcu5Bu0jnBmMPz86aKP1uRL3Y,93
4
4
  edsl/agents/agent.py,sha256=svTVvvg9eCMUhnb49Bxsf9nAwXragtRaeBkyB6q89EE,54423
5
5
  edsl/agents/agent_list.py,sha256=JA39_6RSmiD2mqJgWr2NWovNxNmu4mhZbYmn5be87NQ,21572
@@ -87,7 +87,7 @@ edsl/inference_services/services/mistral_ai_service.py,sha256=Q4eWCAUhsibMaBpq5I
87
87
  edsl/inference_services/services/ollama_service.py,sha256=quSKlgD0bHG9mO_s9verGePfqQi_rZWovHEQ6dy-Fe0,303
88
88
  edsl/inference_services/services/open_ai_service.py,sha256=_gK1MVJGla-LF9YvySNuVDY5g-SmSsNhByEfIO7usAI,8481
89
89
  edsl/inference_services/services/perplexity_service.py,sha256=th6Zx3YNBBc4MsgjzmpkAfqMwqrPNFBdAhmUxed-gYM,5793
90
- edsl/inference_services/services/test_service.py,sha256=ZvqXlshPlo2okPCoDE7xK4qgQalTZN2mM0XEjZmI5jY,2987
90
+ edsl/inference_services/services/test_service.py,sha256=1skcodQ9JN7IsIeaperh7gxeQ_CGEQkO2mamNQTHAx0,3363
91
91
  edsl/inference_services/services/together_ai_service.py,sha256=biUYs07jsrIHp19O81o0nJCwYdSWudMEXdGtmA1-y60,6151
92
92
  edsl/inference_services/services/xai_service.py,sha256=hJbXF26DuFTZdy0lYT1wo3yyuWDcwcXA6EiGYUahK1w,280
93
93
  edsl/inference_services/write_available.py,sha256=9L8chJb8iafHfwRBfqZKjMjkSBRWUa5gEe7F0mxsZu0,261
@@ -112,7 +112,7 @@ edsl/interviews/statistics.py,sha256=lZCtq79QrDKG3jXao_OWuBRhnly9VyuhM6IdTJaYqPg
112
112
  edsl/invigilators/__init__.py,sha256=fKbZ7p9-kMelpvET3Ku2Owu-tL_apC-8gi9JychpMBY,1843
113
113
  edsl/invigilators/exceptions.py,sha256=ejoF-Gt-YcnW1yHyfpJ3jZm8AC_zD0GCYafRO2LlAMQ,2767
114
114
  edsl/invigilators/invigilator_base.py,sha256=DgrXTK4AAxXr4wg2pzc0p1aGPPf1UUt01C-JW1UBTvo,20099
115
- edsl/invigilators/invigilators.py,sha256=UH8gy59qq0_f9jzumDbdugF0SvGW_eIr2GT5zCUO8V0,22355
115
+ edsl/invigilators/invigilators.py,sha256=hY66Nwl1_Y-f_MAs7iqbU36zRQTKQA4JuW2Zi2Rq4qc,22365
116
116
  edsl/invigilators/prompt_constructor.py,sha256=THHGcZPI-QUOH8Z9cQEzH7bZEoo0V_Nc_Phlhc9AzL0,19115
117
117
  edsl/invigilators/prompt_helpers.py,sha256=LuMZFZkInPY8M7Rw9fG9rpJIcT89tr2_Iq10ZHH_Y4A,5409
118
118
  edsl/invigilators/question_instructions_prompt_builder.py,sha256=E5zpwctpt_5JjONkZRcMwB0MACAzDvvnzUhmuWTnjd0,9684
@@ -130,7 +130,7 @@ edsl/jobs/jobs.py,sha256=HI8akFqRbDVEeT8DuIy2i_tyEx6Gnv3oOU7SS0TrmcM,38931
130
130
  edsl/jobs/jobs_checks.py,sha256=bfPJ3hQ4qvRBhyte4g-4J8zExJxJr3nlLHmtVmFPJcQ,5390
131
131
  edsl/jobs/jobs_component_constructor.py,sha256=XxnJCQEJVC99QHNXjhR3lCfzSn46Z0JMtkgHRiBUfj8,6907
132
132
  edsl/jobs/jobs_interview_constructor.py,sha256=1XTfQ-XAsabIagYQWWn9jLkdXAWqw_7KffNVLQWCfDs,2001
133
- edsl/jobs/jobs_pricing_estimation.py,sha256=znHvWlWM8Gc_im1V5TebITpLYEWpJFc1IztJic6i21o,12789
133
+ edsl/jobs/jobs_pricing_estimation.py,sha256=rb4zr0d8DicLmHy2_0l1qVAdskCyBLrXeqtz5Qa60c8,15433
134
134
  edsl/jobs/jobs_remote_inference_logger.py,sha256=1lOlzsBXg69zwVP40Je-WiI4wcvS-Ov7BBuW6V4Mkes,9185
135
135
  edsl/jobs/jobs_runner_asyncio.py,sha256=wSs_Ts__-2BbPqZ_xQG7BM1mQ1YqZFliPUoq9MFuSUY,11034
136
136
  edsl/jobs/jobs_runner_status.py,sha256=hIHHC_sWkK6clqQwnxz8YXAvwrEoL-VVtwWnHij3vfw,10446
@@ -146,7 +146,7 @@ edsl/key_management/models.py,sha256=z9TimNMnz47mnITM5SlJy2m2sk1aKKtt0ybV89rsaiY
146
146
  edsl/language_models/__init__.py,sha256=WtefJs6XOCn5RSz22PgoAi3eTEr1NzGtnnBpDIie2mg,240
147
147
  edsl/language_models/compute_cost.py,sha256=noWk0osCANksfKSh0sXFkPrcQegtSV8-jCRBjz_52uQ,2570
148
148
  edsl/language_models/exceptions.py,sha256=P9dMA8XfK_qcuXNJZ-Xsb_Ny-12Ldu3fPC133RB40Ek,13728
149
- edsl/language_models/language_model.py,sha256=iIe0YxTulrDNwuvn8px6DaLXpcw75oRSLGf0mwmyW4M,39643
149
+ edsl/language_models/language_model.py,sha256=oYxJtE7lBR-1uPnby5-zQc5je0-3OLU0fw3QbQcsbTI,40279
150
150
  edsl/language_models/model.py,sha256=UhBFV7eSgUBub0hR7vpmnerXvLXTX-4Xda2tA_eNJbU,11616
151
151
  edsl/language_models/model_list.py,sha256=Eb62xQdrlayqWYyJVgYxheMiNi14e1U9b_12qYzy1ws,4522
152
152
  edsl/language_models/price_manager.py,sha256=vLqMmrFecdW6aH4csFoM8w_MtRmMGCmi8pb79oS5_EY,5747
@@ -155,7 +155,7 @@ edsl/language_models/registry.py,sha256=HY1fEHKXz92AQF8fIMfkvtA8p-_o9mWwr9rt2VDO
155
155
  edsl/language_models/repair.py,sha256=ljm0xc9e1tMdyKc9b-v7ikpYRBh639xJ11SkDzI2vZE,5245
156
156
  edsl/language_models/unused/fake_openai_call.py,sha256=dxbL5e4NLF-eTk9IduPyGwLiVCX_-eGCJDaLYPlQTqc,364
157
157
  edsl/language_models/unused/fake_openai_service.py,sha256=p0slW9cTdhuCjym64-uOcH_eHu4tzq5CHPPjvY8C2Ok,1691
158
- edsl/language_models/utilities.py,sha256=SMhP6-fs7oU2YU-iphF2mxTnN_tw6spDr2CJfQBBCCk,2235
158
+ edsl/language_models/utilities.py,sha256=WHhSVzBw_ujm226sfxi38uCiAMJn-PC4NarQP7bqUYU,2284
159
159
  edsl/load_plugins.py,sha256=rJJiVHguGoeri4ZT6E3AKftRjibnw-o6JMA9R6Qv3Ng,2480
160
160
  edsl/logger.py,sha256=vnik_w_gHPxdRgF4ctgkuhjBeFwUkDt0c0uVUwWKfy4,4291
161
161
  edsl/notebooks/__init__.py,sha256=5uN54Xgjv4J0f_wdtdLoRnSzSUkHpSNTDtjLE2_jpZg,612
@@ -198,8 +198,8 @@ edsl/questions/question_base.py,sha256=WJMah2OLOoKvLo288sS4PfAWw2kBYM7q0FWW-yDBB
198
198
  edsl/questions/question_base_gen_mixin.py,sha256=Zb1nd0O6NR1c1rf6ik-Im7WPXAiIQrHkZTqK4PPUXSU,9768
199
199
  edsl/questions/question_base_prompts_mixin.py,sha256=YWWAsI-_fzm8UTDbryfnA0g-1ufiGa1QxeZMb6r0T8A,11916
200
200
  edsl/questions/question_budget.py,sha256=C7TmJVk9XT_1Ado2S_JbLOGr4OtRONeR9mp3BoPbif4,24541
201
- edsl/questions/question_check_box.py,sha256=gs5HuVnQRr1C1LRI_OGZt5VcSjtQkPQId4mh6ytyCRc,34065
202
- edsl/questions/question_dict.py,sha256=D3bwvZZqQeaWOebjpnc94G7ItDrDmreDMus3PDbTbZg,20708
201
+ edsl/questions/question_check_box.py,sha256=PNxCae2gAbuSqApGMWOdA2zZ2uhZFv_0O8lm6T8nvhg,33613
202
+ edsl/questions/question_dict.py,sha256=OcKGuA3KpyXn7UjZbC41wIhiIIGxSJySdfoxOtU3Prc,20793
203
203
  edsl/questions/question_extract.py,sha256=6x5LOqwDko_-DnhJAtZBRAju11JIa4PxTjU-5lg1rE0,20227
204
204
  edsl/questions/question_free_text.py,sha256=Oaw7C5BCclCiaWJlWHQJFEPppKxT7zWBFyIbF03LJh0,12879
205
205
  edsl/questions/question_functional.py,sha256=iwFlJmXBoFDu5D4tZ4Ci_yhfQo8_tB9C3W5I2p7KipA,9524
@@ -358,8 +358,8 @@ edsl/utilities/repair_functions.py,sha256=EXkXsqnmgPqj9b3dff1cZnJyaZw-qEvGENXCRH
358
358
  edsl/utilities/restricted_python.py,sha256=248N2p5EWHDSpcK1G-q7DUoJeWy4sB6aO-RV0-5O7uY,2038
359
359
  edsl/utilities/template_loader.py,sha256=SCAcnTnxNQ67MNSkmfz7F-S_u2peyGn2j1oRIqi1wfg,870
360
360
  edsl/utilities/utilities.py,sha256=irHheAGOnl_6RwI--Hi9StVzvsHcWCqB48PWsWJQYOw,12045
361
- edsl-0.1.53.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
362
- edsl-0.1.53.dist-info/METADATA,sha256=WUkrcqMnf8uKQvTyrQTx0q3oVFDurmcI3HkXz9Ljk6g,12670
363
- edsl-0.1.53.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
364
- edsl-0.1.53.dist-info/entry_points.txt,sha256=JnG7xqMtHaQu9BU-yPATxdyCeA48XJpuclnWCqMfIMU,38
365
- edsl-0.1.53.dist-info/RECORD,,
361
+ edsl-0.1.54.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
362
+ edsl-0.1.54.dist-info/METADATA,sha256=NGU-XmzH8XskOALpmyMCfowQaFzeGwHkdvBskv1BBns,12671
363
+ edsl-0.1.54.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
364
+ edsl-0.1.54.dist-info/entry_points.txt,sha256=JnG7xqMtHaQu9BU-yPATxdyCeA48XJpuclnWCqMfIMU,38
365
+ edsl-0.1.54.dist-info/RECORD,,
File without changes
File without changes