dcicutils 8.10.0.1b2__py3-none-any.whl → 8.11.0__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.
@@ -7,7 +7,6 @@ import os
7
7
  import re
8
8
  import requests
9
9
  import subprocess
10
- import sys
11
10
 
12
11
  from typing import Callable, Optional
13
12
  from .exceptions import InvalidParameterError
@@ -373,7 +372,7 @@ def script_catch_errors():
373
372
  raise ScriptFailure(' '.join(message))
374
373
  try:
375
374
  yield fail
376
- sys.exit(0)
375
+ exit(0)
377
376
  except (Exception, ScriptFailure) as e:
378
377
  if DEBUG_SCRIPT:
379
378
  # If debugging, let the error propagate, do not trap it.
@@ -385,7 +384,7 @@ def script_catch_errors():
385
384
  else:
386
385
  message = str(e) # Note: We ignore the type, which isn't intended to be shown.
387
386
  PRINT(message)
388
- sys.exit(1)
387
+ exit(1)
389
388
 
390
389
 
391
390
  class Question:
@@ -396,9 +396,9 @@ class EBDeployer:
396
396
  packaging_was_successful = cls.build_application_version(args.repo, args.version_name, branch=args.branch)
397
397
  if packaging_was_successful: # XXX: how to best detect?
398
398
  time.sleep(5) # give EB a second to catch up (it needs it)
399
- sys.exit(cls.deploy_new_version(args.env, args.repo, args.version_name))
399
+ exit(cls.deploy_new_version(args.env, args.repo, args.version_name))
400
400
  else:
401
- sys.exit(cls.deploy_indexer(args.env, args.application_version))
401
+ exit(cls.deploy_indexer(args.env, args.application_version))
402
402
 
403
403
 
404
404
  class IniFileManager:
dcicutils/ecr_scripts.py CHANGED
@@ -3,7 +3,6 @@ import botocore.exceptions
3
3
  import boto3
4
4
  import contextlib
5
5
  import os
6
- import sys
7
6
 
8
7
  from typing import Optional, Union, List
9
8
  from .command_utils import yes_or_no
@@ -69,7 +68,7 @@ def ecr_command_context(account_number, ecs_repository=None, ecr_client=None):
69
68
  elif account_number != account_number_in_environ:
70
69
  raise RuntimeError("The account number you have specified does not match your declared credentials.")
71
70
  yield ECRCommandContext(account_number=account_number, ecs_repository=ecs_repository, ecr_client=ecr_client)
72
- sys.exit(0)
71
+ exit(0)
73
72
  except botocore.exceptions.ClientError as e:
74
73
  error_info = e.response.get('Error', {})
75
74
  message = error_info.get('Message')
@@ -78,12 +77,12 @@ def ecr_command_context(account_number, ecs_repository=None, ecr_client=None):
78
77
  raise RuntimeError("Your security token seems to have expired.")
79
78
  elif message:
80
79
  PRINT(f"{code}: {message}")
81
- sys.exit(1)
80
+ exit(1)
82
81
  else:
83
82
  raise
84
83
  except Exception as e:
85
84
  PRINT(f"{full_class_name(e)}: {e}")
86
- sys.exit(1)
85
+ exit(1)
87
86
 
88
87
 
89
88
  class ECRCommandContext:
dcicutils/env_scripts.py CHANGED
@@ -1,7 +1,6 @@
1
1
  import argparse
2
2
  import boto3
3
3
  import json
4
- import sys
5
4
  import yaml
6
5
 
7
6
  from .lang_utils import disjoined_list
@@ -53,7 +52,7 @@ def show_global_env_bucket(bucket, mode='json', key=None):
53
52
  else:
54
53
  PRINT(f"There is no default bucket. Please use a '--bucket' argument"
55
54
  f" to specify one of {disjoined_list(envs_buckets)}.")
56
- sys.exit(1)
55
+ exit(1)
57
56
 
58
57
  print_heading(bucket, style='=')
59
58
 
@@ -71,7 +70,7 @@ def show_global_env_bucket(bucket, mode='json', key=None):
71
70
  except Exception as e:
72
71
  PRINT("Bucket contents could not be downlaoded.")
73
72
  print_error_message(e)
74
- sys.exit(1)
73
+ exit(1)
75
74
 
76
75
  object = None # Without this, PyCharm fusses that object might not get set. -kmp 20-Jul-2022
77
76
  try:
@@ -79,7 +78,7 @@ def show_global_env_bucket(bucket, mode='json', key=None):
79
78
  except Exception as e:
80
79
  PRINT("Bucket contents could not be parsed as JSON.")
81
80
  print_error_message(e)
82
- sys.exit(1)
81
+ exit(1)
83
82
 
84
83
  if mode == 'json':
85
84
  PRINT(json.dumps(object, indent=2, default=str))
@@ -87,7 +86,7 @@ def show_global_env_bucket(bucket, mode='json', key=None):
87
86
  PRINT(yaml.dump(object))
88
87
  else:
89
88
  PRINT(f"Unknown mode: {mode}. Try 'json' or 'yaml'.")
90
- sys.exit(1)
89
+ exit(1)
91
90
 
92
91
 
93
92
  DEFAULT_BUCKET = get_env_bucket()
@@ -248,12 +248,6 @@
248
248
  "docutils" // Used only privately as a separate documentation-generation task for ReadTheDocs
249
249
  ],
250
250
 
251
-
252
- "GNU General Public License v2 (GPLv2)": [
253
- "pyinstaller",
254
- "pyinstaller-hooks-contrib"
255
- ],
256
-
257
251
  "MIT/X11 Derivative": [
258
252
  // The license used by libxkbcommon is complicated and involves numerous included licenses,
259
253
  // but all are permissive.
dcicutils/progress_bar.py CHANGED
@@ -249,7 +249,7 @@ class ProgressBar:
249
249
  if self._interrupt_exit_message:
250
250
  if isinstance(interrupt_exit_message := self._interrupt_exit_message(self), str):
251
251
  print(interrupt_exit_message)
252
- sys.exit(1)
252
+ exit(1)
253
253
  elif interrupt_stop is False or ((interrupt_stop is None) and (self._interrupt_exit is False)):
254
254
  set_interrupt_handler(handle_interrupt)
255
255
  interrupt_continue = self._interrupt_continue(self) if self._interrupt_continue else None
dcicutils/schema_utils.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  from typing import Any, Dict, List, Optional, Tuple
3
+
3
4
  from dcicutils.misc_utils import to_camel_case
4
5
 
5
6
 
@@ -8,6 +9,7 @@ class JsonSchemaConstants:
8
9
  ARRAY = "array"
9
10
  BOOLEAN = "boolean"
10
11
  DEFAULT = "default"
12
+ DEPENDENT_REQUIRED = "dependentRequired"
11
13
  ENUM = "enum"
12
14
  FORMAT = "format"
13
15
  INTEGER = "integer"
@@ -29,6 +31,10 @@ class EncodedSchemaConstants:
29
31
  LINK_TO = "linkTo"
30
32
  MERGE_REF = "$merge"
31
33
  MIXIN_PROPERTIES = "mixinProperties"
34
+ SUBMISSION_COMMENT = "submissionComment"
35
+ SUBMISSION_EXAMPLES = "submissionExamples"
36
+ SUBMITTER_REQUIRED = "submitterRequired"
37
+ SUGGESTED_ENUM = "suggested_enum"
32
38
  UNIQUE_KEY = "uniqueKey"
33
39
 
34
40
 
@@ -203,6 +209,50 @@ def get_description(schema: Dict[str, Any]) -> str:
203
209
  return schema.get(SchemaConstants.DESCRIPTION, "")
204
210
 
205
211
 
212
+ def is_submitter_required(schema: Dict[str, Any]) -> bool:
213
+ """Return True if the schema is marked as required for submitters.
214
+
215
+ Specifically, required for external (i.e. non-admin) submitters.
216
+
217
+ This is typically validated within the context of a oneOf, anyOf,
218
+ or allOf schema on an item type which is used within the team and
219
+ by external submitters, and is tricky to pick up on automatically.
220
+ """
221
+ return schema.get(SchemaConstants.SUBMITTER_REQUIRED, False)
222
+
223
+
224
+ def get_submission_comment(schema: Dict[str, Any]) -> str:
225
+ """Return the submission comment for a property.
226
+
227
+ Custom property that can be manually added to a schema to provide
228
+ additional context for submitters.
229
+ """
230
+ return schema.get(SchemaConstants.SUBMISSION_COMMENT, "")
231
+
232
+
233
+ def get_submission_examples(schema: Dict[str, Any]) -> List[str]:
234
+ """Return the submission example for a property.
235
+
236
+ Custom property that can be manually added to a schema to provide
237
+ an example for submitters.
238
+ """
239
+ return schema.get(SchemaConstants.SUBMISSION_EXAMPLES, [])
240
+
241
+
242
+ def get_suggested_enum(schema: Dict[str, Any]) -> List[str]:
243
+ """Return the suggested enum for a property.
244
+
245
+ Custom property that can be manually added to a schema to provide
246
+ a suggested list of values for submitters.
247
+ """
248
+ return schema.get(SchemaConstants.SUGGESTED_ENUM, [])
249
+
250
+
251
+ def get_dependent_required(schema: Dict[str, Any]) -> Dict[str, List[str]]:
252
+ """Return the dependent required properties of a schema."""
253
+ return schema.get(SchemaConstants.DEPENDENT_REQUIRED, {})
254
+
255
+
206
256
  class Schema:
207
257
 
208
258
  def __init__(self, schema: dict, type: Optional[str] = None) -> None:
@@ -33,7 +33,6 @@ import argparse
33
33
  import os
34
34
  import requests
35
35
  import subprocess
36
- import sys
37
36
  import toml
38
37
 
39
38
  from typing import Tuple, Union
@@ -336,7 +335,7 @@ def exit_with_no_action() -> None:
336
335
  first prints a message saying no action was taken.
337
336
  """
338
337
  PRINT("Exiting without taking action.")
339
- sys.exit(1)
338
+ exit(1)
340
339
 
341
340
 
342
341
  PRINT = print
@@ -201,17 +201,17 @@ def main():
201
201
  return
202
202
  else:
203
203
  _print(f"No PATCH data found in file: {args.patch}")
204
- sys.exit(1)
204
+ exit(1)
205
205
 
206
206
  data = _get_portal_object(portal=portal, uuid=args.uuid, raw=args.raw,
207
207
  database=args.database, check=args.bool, verbose=args.verbose)
208
208
  if args.bool:
209
209
  if data:
210
210
  _print(f"{args.uuid}: found")
211
- sys.exit(0)
211
+ exit(0)
212
212
  else:
213
213
  _print(f"{args.uuid}: not found")
214
- sys.exit(1)
214
+ exit(1)
215
215
  if args.copy:
216
216
  pyperclip.copy(json.dumps(data, indent=4))
217
217
  if args.yaml:
@@ -597,18 +597,18 @@ def _print_tree(root_name: Optional[str],
597
597
  def _read_json_from_file(file: str) -> Optional[dict]:
598
598
  if not os.path.exists(file):
599
599
  _print(f"Cannot find file: {file}")
600
- sys.exit(1)
600
+ exit(1)
601
601
  try:
602
602
  with io.open(file, "r") as f:
603
603
  try:
604
604
  return json.load(f)
605
605
  except Exception:
606
606
  _print(f"Cannot parse JSON in file: {file}")
607
- sys.exit(1)
607
+ exit(1)
608
608
  except Exception as e:
609
609
  print(e)
610
610
  _print(f"Cannot open file: {file}")
611
- sys.exit(1)
611
+ exit(1)
612
612
 
613
613
 
614
614
  def _print(*args, **kwargs):
@@ -620,7 +620,7 @@ def _print(*args, **kwargs):
620
620
  def _exit(message: Optional[str] = None) -> None:
621
621
  if message:
622
622
  _print(f"ERROR: {message}")
623
- sys.exit(1)
623
+ exit(1)
624
624
 
625
625
 
626
626
  if __name__ == "__main__":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dcicutils
3
- Version: 8.10.0.1b2
3
+ Version: 8.11.0
4
4
  Summary: Utility package for interacting with the 4DN Data Portal and other 4DN resources
5
5
  Home-page: https://github.com/4dn-dcic/utils
6
6
  License: MIT
@@ -5,7 +5,7 @@ dcicutils/bundle_utils.py,sha256=ZVQcqlt7Yly8-YbL3A-5DW859_hMWpTL6dXtknEYZIw,346
5
5
  dcicutils/captured_output.py,sha256=0hP7sPwleMaYXQAvCfJOxG8Z8T_JJYy8ADp8A5ZoblE,3295
6
6
  dcicutils/cloudformation_utils.py,sha256=MtWJrSTXyiImgbPHgRvfH9bWso20ZPLTFJAfhDQSVj4,13786
7
7
  dcicutils/codebuild_utils.py,sha256=CKpmhJ-Z8gYbkt1I2zyMlKtFdsg7T8lqrx3V5ieta-U,1155
8
- dcicutils/command_utils.py,sha256=4LkszKXWlvgaUP_7d_tRsRqpOMc9IaohD2Kc9u9bEeU,18506
8
+ dcicutils/command_utils.py,sha256=1_h18LGX86sLAkRkH33HNmBkwMb7v2wAh3jL01hzceU,18487
9
9
  dcicutils/common.py,sha256=YE8Mt5-vaZWWz4uaChSVhqGFbFtW5QKtnIyOr4zG4vM,3955
10
10
  dcicutils/contribution_scripts.py,sha256=0k5Gw1TumcD5SAcXVkDd6-yvuMEw-jUp5Kfb7FJH6XQ,2015
11
11
  dcicutils/contribution_utils.py,sha256=vYLS1JUB3sKd24BUxZ29qUBqYeQBLK9cwo8x3k64uPg,25653
@@ -13,15 +13,15 @@ dcicutils/creds_utils.py,sha256=64BbIfS90T1eJmmQJrDyfrRa3V2F1x7T8lOrEeFfqJY,1112
13
13
  dcicutils/data_readers.py,sha256=6EMrY7TjDE8H7bA_TCWtpLQP7slJ0YTL77_dNh6e7sg,7626
14
14
  dcicutils/data_utils.py,sha256=k2OxOlsx7AJ6jF-YNlMyGus_JqSUBe4_n1s65Mv1gQQ,3098
15
15
  dcicutils/datetime_utils.py,sha256=sM653aw_1zy1qBmfAH-WetCi2Fw9cnFK7FZN_Tg4onI,13499
16
- dcicutils/deployment_utils.py,sha256=6Sv1cM9T944d_9CTJt8O2RPtpw9MiTIPKw_DgYLOnCU,69916
16
+ dcicutils/deployment_utils.py,sha256=sKv8Jb-_Zw2aH3OAywRlsre-Cqm3a7fEGG3_1PT-r-s,69908
17
17
  dcicutils/diff_utils.py,sha256=sQx-yz56DHAcQWOChYbAG3clXu7TbiZKlw-GggeveO0,8118
18
18
  dcicutils/docker_utils.py,sha256=30gUiqz7X9rJwSPXTPn4ewjQibUgoSJqhP9o9vn5X-A,1747
19
- dcicutils/ecr_scripts.py,sha256=puiWqjIshGWNc7ErJvkyizQRINoDToDu7DXHM9ouKMc,19497
19
+ dcicutils/ecr_scripts.py,sha256=cxDl4BQt5W9NN1zjOHYZ7kk3yqoMnaCfNIyLaYmCqdE,19474
20
20
  dcicutils/ecr_utils.py,sha256=V1Eif-6THI38W1uKXUyYs-5ciYAVkGLv0sVS4xoh70o,13079
21
21
  dcicutils/ecs_utils.py,sha256=1sIIY5IVb__rNyZ5B9iIQKHiUIMldB7JRaeIISLaujY,3590
22
22
  dcicutils/env_base.py,sha256=KQmChAvX9riF_khDlW4hmlrHO0GqFMNXrFdiuSmbZtc,6356
23
23
  dcicutils/env_manager.py,sha256=Nte1oiW_AQ-isatzsf-fiNpPWInLdfRxzPrATdNoKkI,9444
24
- dcicutils/env_scripts.py,sha256=gAoXOemg-zA4I_IPeRuymIfhNOYCw_WmPUa6kcSiWkg,3936
24
+ dcicutils/env_scripts.py,sha256=0YcEKn7MLLx_St_n74Oe7RlIs7xt3GA0mE04eqrTrfg,3909
25
25
  dcicutils/env_utils.py,sha256=hJTXsn6GC55-55ja1ERBmUbeh-DjJABm74eYRGRaiSc,46970
26
26
  dcicutils/env_utils_legacy.py,sha256=J81OAtJHN69o1beHO6q1j7_J6TeblSjnAHlS8VA5KSM,29032
27
27
  dcicutils/es_utils.py,sha256=ZksLh5ei7kRUfiFltk8sd2ZSfh15twbstrMzBr8HNw4,7541
@@ -39,7 +39,7 @@ dcicutils/lang_utils.py,sha256=MI3K6bPHLUqlkx3s_9jYZfbGbahiQFlpq4rBE3OYMbg,28151
39
39
  dcicutils/license_policies/c4-infrastructure.jsonc,sha256=xEQbIN08Y2xh3gSLRtSz9EhAZox1p3kHC4r678hCpss,278
40
40
  dcicutils/license_policies/c4-python-infrastructure.jsonc,sha256=Tkq8P1mKGYlix68I82IFNmasrT4wtSdokOIM-g2B8DQ,296
41
41
  dcicutils/license_policies/park-lab-common-server.jsonc,sha256=aaK-NdFDT8f8z_gBXihZnQJ6g3CAZdGSlHOwUP8HvUQ,5790
42
- dcicutils/license_policies/park-lab-common.jsonc,sha256=QyzpPveVr87RMpjrLLhnxLSp4VuEWta1gehMAqgKKig,18995
42
+ dcicutils/license_policies/park-lab-common.jsonc,sha256=0LIFlIQWmdHlt160ku8cTOiB59akgYzRhRN3Xb5G_Aw,18864
43
43
  dcicutils/license_policies/park-lab-gpl-pipeline.jsonc,sha256=vLZkwm3Js-kjV44nug3PizRGDLVnDox4CnvDKu5d2oQ,3260
44
44
  dcicutils/license_policies/park-lab-pipeline.jsonc,sha256=9qlY0ASy3iUMQlr3gorVcXrSfRHnVGbLhkS427UaRy4,283
45
45
  dcicutils/license_utils.py,sha256=d1cq6iwv5Ju-VjdoINi6q7CPNNL7Oz6rcJdLMY38RX0,46978
@@ -49,17 +49,17 @@ dcicutils/obfuscation_utils.py,sha256=fo2jOmDRC6xWpYX49u80bVNisqRRoPskFNX3ymFAmj
49
49
  dcicutils/opensearch_utils.py,sha256=V2exmFYW8Xl2_pGFixF4I2Cc549Opwe4PhFi5twC0M8,1017
50
50
  dcicutils/portal_object_utils.py,sha256=Az3n1aL-PQkN5gOFE6ZqC2XkYsqiwKlq7-tZggs1QN4,11062
51
51
  dcicutils/portal_utils.py,sha256=R7v4uQUll34mn-NxyU3qoTouAwWrVDzW6W1zBGSU-M4,44762
52
- dcicutils/progress_bar.py,sha256=R3bWLMYM3Xq9PY7U0JadcFT1m7QmCbrbDp9qs9_Kf_c,19472
52
+ dcicutils/progress_bar.py,sha256=UT7lxb-rVF_gp4yjY2Tg4eun1naaH__hB4_v3O85bcE,19468
53
53
  dcicutils/project_utils.py,sha256=qPdCaFmWUVBJw4rw342iUytwdQC0P-XKpK4mhyIulMM,31250
54
54
  dcicutils/qa_checkers.py,sha256=cdXjeL0jCDFDLT8VR8Px78aS10hwNISOO5G_Zv2TZ6M,20534
55
55
  dcicutils/qa_utils.py,sha256=TT0SiJWiuxYvbsIyhK9VO4uV_suxhB6CpuC4qPacCzQ,160208
56
56
  dcicutils/redis_tools.py,sha256=qkcSNMtvqkpvts-Cm9gWhneK523Q_oHwhNUud1be1qk,7055
57
57
  dcicutils/redis_utils.py,sha256=VJ-7g8pOZqR1ZCtdcjKz3-6as2DMUcs1b1zG6wSprH4,6462
58
58
  dcicutils/s3_utils.py,sha256=LauLFQGvZLfpBJ81tYMikjLd3SJRz2R_FrL1n4xSlyI,28868
59
- dcicutils/schema_utils.py,sha256=IIteRrg-iOJOFU17n2lvKByVdWdiMfuAQ1kf_QIM96Q,10604
60
- dcicutils/scripts/publish_to_pypi.py,sha256=JCrAiYFF9lMkj3s2w0J2EtN8P65qEamMe3ZZYPCF4Yo,13904
59
+ dcicutils/schema_utils.py,sha256=GmRm-XqZKJ6qine16SQF1txcby9WougDav_sYmKNs9E,12400
60
+ dcicutils/scripts/publish_to_pypi.py,sha256=LFzNHIQK2EXFr88YcfctyA_WKEBFc1ElnSjWrCXedPM,13889
61
61
  dcicutils/scripts/run_license_checker.py,sha256=z2keYnRDZsHQbTeo1XORAXSXNJK5axVzL5LjiNqZ7jE,4184
62
- dcicutils/scripts/view_portal_object.py,sha256=rnlIoblDpoLPJ-Bor7OHxLgrVZyvqoxA0jmHW8ogg3s,29805
62
+ dcicutils/scripts/view_portal_object.py,sha256=HZzM44BDcGycO9XTOTZyP-F7PRMZaZrnFfiqiT7Qvqg,29777
63
63
  dcicutils/secrets_utils.py,sha256=8dppXAsiHhJzI6NmOcvJV5ldvKkQZzh3Fl-cb8Wm7MI,19745
64
64
  dcicutils/sheet_utils.py,sha256=VlmzteONW5VF_Q4vo0yA5vesz1ViUah1MZ_yA1rwZ0M,33629
65
65
  dcicutils/snapshot_utils.py,sha256=ymP7PXH6-yEiXAt75w0ldQFciGNqWBClNxC5gfX2FnY,22961
@@ -73,8 +73,8 @@ dcicutils/trace_utils.py,sha256=g8kwV4ebEy5kXW6oOrEAUsurBcCROvwtZqz9fczsGRE,1769
73
73
  dcicutils/validation_utils.py,sha256=cMZIU2cY98FYtzK52z5WUYck7urH6JcqOuz9jkXpqzg,14797
74
74
  dcicutils/variant_utils.py,sha256=2H9azNx3xAj-MySg-uZ2SFqbWs4kZvf61JnK6b-h4Qw,4343
75
75
  dcicutils/zip_utils.py,sha256=_Y9EmL3D2dUZhxucxHvrtmmlbZmK4FpSsHEb7rGSJLU,3265
76
- dcicutils-8.10.0.1b2.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
77
- dcicutils-8.10.0.1b2.dist-info/METADATA,sha256=KmlGHSWKamA0Ry44aKGV2kgQNs4f0Qxi3XrxHvcDE0I,3440
78
- dcicutils-8.10.0.1b2.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
79
- dcicutils-8.10.0.1b2.dist-info/entry_points.txt,sha256=51Q4F_2V10L0282W7HFjP4jdzW4K8lnWDARJQVFy_hw,270
80
- dcicutils-8.10.0.1b2.dist-info/RECORD,,
76
+ dcicutils-8.11.0.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
77
+ dcicutils-8.11.0.dist-info/METADATA,sha256=fyL2AYscpmbInho84YaFcHMIhk_YTUXPw3MvvmPO9s0,3436
78
+ dcicutils-8.11.0.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
79
+ dcicutils-8.11.0.dist-info/entry_points.txt,sha256=51Q4F_2V10L0282W7HFjP4jdzW4K8lnWDARJQVFy_hw,270
80
+ dcicutils-8.11.0.dist-info/RECORD,,