testit-python-commons 5.1.6__py3-none-any.whl → 5.2.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.
@@ -90,9 +90,9 @@ class CustomAttributeApiResult(ModelNormal):
90
90
  'is_enabled': (bool,), # noqa: E501
91
91
  'is_required': (bool,), # noqa: E501
92
92
  'is_global': (bool,), # noqa: E501
93
- 'is_read_only': (bool, none_type,), # noqa: E501
94
- 'is_system': (bool, none_type,), # noqa: E501
95
- 'targets': ([str], none_type,), # noqa: E501
93
+ 'is_read_only': (bool,), # noqa: E501
94
+ 'is_system': (bool,), # noqa: E501
95
+ 'targets': ([str],), # noqa: E501
96
96
  'code': (str, none_type,), # noqa: E501
97
97
  }
98
98
 
@@ -123,7 +123,7 @@ class CustomAttributeApiResult(ModelNormal):
123
123
 
124
124
  @classmethod
125
125
  @convert_js_args_to_python_args
126
- def _from_openapi_data(cls, id, options, type, is_deleted, name, is_enabled, is_required, is_global, *args, **kwargs): # noqa: E501
126
+ def _from_openapi_data(cls, id, options, type, is_deleted, name, is_enabled, is_required, is_global, is_read_only, is_system, targets, *args, **kwargs): # noqa: E501
127
127
  """CustomAttributeApiResult - a model defined in OpenAPI
128
128
 
129
129
  Args:
@@ -135,11 +135,11 @@ class CustomAttributeApiResult(ModelNormal):
135
135
  is_enabled (bool): Indicates if the attribute is enabled
136
136
  is_required (bool): Indicates if the attribute value is mandatory to specify
137
137
  is_global (bool): Indicates if the attribute is available across all projects
138
+ is_read_only (bool): Indicates if the attribute is read-only
139
+ is_system (bool): Indicates if the attribute is system
140
+ targets ([str]): Collection of the attribute targets Defines where the attribute can be used (e.g., TestCases, AutoTestCases, TestPlans)
138
141
 
139
142
  Keyword Args:
140
- is_read_only (bool): Indicates if the attribute is read-only. [optional] # noqa: E501
141
- is_system (bool): Indicates if the attribute is system. [optional] # noqa: E501
142
- targets ([str]): Collection of the attribute targets. [optional] # noqa: E501
143
143
  _check_type (bool): if True, values for parameters in openapi_types
144
144
  will be type checked and a TypeError will be
145
145
  raised if the wrong type is input.
@@ -178,9 +178,6 @@ class CustomAttributeApiResult(ModelNormal):
178
178
  _path_to_item = kwargs.pop('_path_to_item', ())
179
179
  _configuration = kwargs.pop('_configuration', None)
180
180
  _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
181
- is_read_only = kwargs.pop('is_read_only', False)
182
- is_system = kwargs.pop('is_system', False)
183
- targets = kwargs.pop('targets', None)
184
181
 
185
182
  self = super(OpenApiModel, cls).__new__(cls)
186
183
 
@@ -236,7 +233,7 @@ class CustomAttributeApiResult(ModelNormal):
236
233
  ])
237
234
 
238
235
  @convert_js_args_to_python_args
239
- def __init__(self, id, options, type, is_deleted, name, is_enabled, is_required, is_global, *args, **kwargs): # noqa: E501
236
+ def __init__(self, id, options, type, is_deleted, name, is_enabled, is_required, is_global, is_read_only, is_system, targets, *args, **kwargs): # noqa: E501
240
237
  """CustomAttributeApiResult - a model defined in OpenAPI
241
238
 
242
239
  Args:
@@ -248,11 +245,11 @@ class CustomAttributeApiResult(ModelNormal):
248
245
  is_enabled (bool): Indicates if the attribute is enabled
249
246
  is_required (bool): Indicates if the attribute value is mandatory to specify
250
247
  is_global (bool): Indicates if the attribute is available across all projects
248
+ is_read_only (bool): Indicates if the attribute is read-only
249
+ is_system (bool): Indicates if the attribute is system
250
+ targets ([str]): Collection of the attribute targets Defines where the attribute can be used (e.g., TestCases, AutoTestCases, TestPlans)
251
251
 
252
252
  Keyword Args:
253
- is_read_only (bool): Indicates if the attribute is read-only. [optional] # noqa: E501
254
- is_system (bool): Indicates if the attribute is system. [optional] # noqa: E501
255
- targets ([str]): Collection of the attribute targets. [optional] # noqa: E501
256
253
  _check_type (bool): if True, values for parameters in openapi_types
257
254
  will be type checked and a TypeError will be
258
255
  raised if the wrong type is input.
@@ -291,9 +288,6 @@ class CustomAttributeApiResult(ModelNormal):
291
288
  _path_to_item = kwargs.pop('_path_to_item', ())
292
289
  _configuration = kwargs.pop('_configuration', None)
293
290
  _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
294
- is_read_only = kwargs.pop('is_read_only', False)
295
- is_system = kwargs.pop('is_system', False)
296
- targets = kwargs.pop('targets', None)
297
291
 
298
292
  if args:
299
293
  for arg in args:
@@ -53,6 +53,7 @@ class LayerSource(ModelSimple):
53
53
  allowed_values = {
54
54
  ('value',): {
55
55
  'MANUAL': "Manual",
56
+ 'REPORT': "Report",
56
57
  'RUN': "Run",
57
58
  'RULE': "Rule",
58
59
  },
@@ -106,10 +107,10 @@ class LayerSource(ModelSimple):
106
107
  Note that value can be passed either in args or in kwargs, but not in both.
107
108
 
108
109
  Args:
109
- args[0] (str):, must be one of ["Manual", "Run", "Rule", ] # noqa: E501
110
+ args[0] (str):, must be one of ["Manual", "Report", "Run", "Rule", ] # noqa: E501
110
111
 
111
112
  Keyword Args:
112
- value (str):, must be one of ["Manual", "Run", "Rule", ] # noqa: E501
113
+ value (str):, must be one of ["Manual", "Report", "Run", "Rule", ] # noqa: E501
113
114
  _check_type (bool): if True, values for parameters in openapi_types
114
115
  will be type checked and a TypeError will be
115
116
  raised if the wrong type is input.
@@ -200,10 +201,10 @@ class LayerSource(ModelSimple):
200
201
  Note that value can be passed either in args or in kwargs, but not in both.
201
202
 
202
203
  Args:
203
- args[0] (str):, must be one of ["Manual", "Run", "Rule", ] # noqa: E501
204
+ args[0] (str):, must be one of ["Manual", "Report", "Run", "Rule", ] # noqa: E501
204
205
 
205
206
  Keyword Args:
206
- value (str):, must be one of ["Manual", "Run", "Rule", ] # noqa: E501
207
+ value (str):, must be one of ["Manual", "Report", "Run", "Rule", ] # noqa: E501
207
208
  _check_type (bool): if True, values for parameters in openapi_types
208
209
  will be type checked and a TypeError will be
209
210
  raised if the wrong type is input.
testit.py CHANGED
@@ -5,6 +5,7 @@ from testit_python_commons.decorators import (
5
5
  externalID,
6
6
  externalId,
7
7
  labels,
8
+ layer,
8
9
  tags,
9
10
  link,
10
11
  links,
@@ -32,6 +33,7 @@ from testit_python_commons.dynamic_methods import (
32
33
  message
33
34
  )
34
35
  from testit_python_commons.models import LinkType
36
+ from testit_python_commons.models.test_layers import TestLayers
35
37
  from testit_python_commons.step import step
36
38
 
37
39
  __all__ = [
@@ -45,6 +47,7 @@ __all__ = [
45
47
  'title',
46
48
  'description',
47
49
  'labels',
50
+ 'layer',
48
51
  'tags',
49
52
  'link',
50
53
  'links',
@@ -65,5 +68,6 @@ __all__ = [
65
68
  'addTags',
66
69
  'addParameter',
67
70
  'step',
68
- 'LinkType'
71
+ 'LinkType',
72
+ 'TestLayers',
69
73
  ]
@@ -36,6 +36,8 @@ from adapters_api.models import (
36
36
  TestStatusApiType,
37
37
  CreateLinkApiModel,
38
38
  LabelApiModel,
39
+ AutoTestCreateApiModelLayer,
40
+ LayerSource,
39
41
  )
40
42
 
41
43
  from testit_python_commons.models.link import Link
@@ -241,6 +243,36 @@ class Converter:
241
243
 
242
244
  return label_models or None
243
245
 
246
+ @staticmethod
247
+ @adapter_logger
248
+ def layer_to_api_model(layer: Optional[str]) -> Optional[AutoTestCreateApiModelLayer]:
249
+ if not layer or not str(layer).strip():
250
+ return None
251
+
252
+ return AutoTestCreateApiModelLayer(
253
+ name=str(layer).strip(),
254
+ source=LayerSource("Run"),
255
+ )
256
+
257
+ @classmethod
258
+ @adapter_logger
259
+ def _autotest_layer_kwargs_for_create(cls, test_result: TestResult) -> dict:
260
+ layer = cls.layer_to_api_model(test_result.get_layer())
261
+ if not layer:
262
+ return {}
263
+
264
+ return {'layer': layer}
265
+
266
+ @classmethod
267
+ @adapter_logger
268
+ def _autotest_layer_kwargs_for_update(cls, test_result: TestResult) -> dict:
269
+ kwargs = {'reset_layer': False}
270
+ layer = cls.layer_to_api_model(test_result.get_layer())
271
+ if layer:
272
+ kwargs['layer'] = layer
273
+
274
+ return kwargs
275
+
244
276
  @classmethod
245
277
  @adapter_logger
246
278
  def test_result_to_autotest_post_model(
@@ -265,7 +297,8 @@ class Converter:
265
297
  labels=cls.labels_to_label_api_models(test_result.get_labels()),
266
298
  tags=test_result.get_tags(),
267
299
  should_create_work_item=test_result.get_automatic_creation_test_cases(),
268
- external_key=test_result.get_external_key()
300
+ external_key=test_result.get_external_key(),
301
+ **cls._autotest_layer_kwargs_for_create(test_result),
269
302
  )
270
303
 
271
304
  @classmethod
@@ -292,7 +325,8 @@ class Converter:
292
325
  labels=cls.labels_to_label_api_models(test_result.get_labels()),
293
326
  tags=test_result.get_tags(),
294
327
  should_create_work_item=test_result.get_automatic_creation_test_cases(),
295
- external_key=test_result.get_external_key()
328
+ external_key=test_result.get_external_key(),
329
+ **cls._autotest_layer_kwargs_for_create(test_result),
296
330
  )
297
331
 
298
332
  @classmethod
@@ -305,7 +339,6 @@ class Converter:
305
339
  external_id=test_result.get_external_id(),
306
340
  project_id=project_id,
307
341
  name=test_result.get_autotest_name(),
308
- reset_layer=False,
309
342
  steps=cls.step_results_to_autotest_steps_model(
310
343
  test_result.get_step_results()),
311
344
  setup=cls.step_results_to_autotest_steps_model(
@@ -319,7 +352,8 @@ class Converter:
319
352
  links=cls.links_to_links_put_model(test_result.get_links()),
320
353
  labels=cls.labels_to_label_api_models(test_result.get_labels()),
321
354
  tags=test_result.get_tags(),
322
- external_key=test_result.get_external_key()
355
+ external_key=test_result.get_external_key(),
356
+ **cls._autotest_layer_kwargs_for_update(test_result),
323
357
  )
324
358
 
325
359
  @classmethod
@@ -332,7 +366,6 @@ class Converter:
332
366
  external_id=test_result.get_external_id(),
333
367
  project_id=project_id,
334
368
  name=test_result.get_autotest_name(),
335
- reset_layer=False,
336
369
  steps=cls.step_results_to_autotest_steps_model(
337
370
  test_result.get_step_results()),
338
371
  setup=cls.step_results_to_autotest_steps_model(
@@ -346,7 +379,8 @@ class Converter:
346
379
  links=cls.links_to_links_put_model(test_result.get_links()),
347
380
  labels=cls.labels_to_label_api_models(test_result.get_labels()),
348
381
  tags=test_result.get_tags(),
349
- external_key=test_result.get_external_key()
382
+ external_key=test_result.get_external_key(),
383
+ **cls._autotest_layer_kwargs_for_update(test_result),
350
384
  )
351
385
 
352
386
  @classmethod
@@ -171,6 +171,18 @@ def tags(*test_tags: str):
171
171
  return outer
172
172
 
173
173
 
174
+ @adapter_logger
175
+ def layer(test_layer: str):
176
+ """
177
+ specifies the test pyramid layer for the autotest card
178
+ """
179
+ def outer(function):
180
+ function.test_layer = test_layer
181
+ return inner(function)
182
+
183
+ return outer
184
+
185
+
174
186
  @Utils.deprecated('Use "links" instead.')
175
187
  @adapter_logger
176
188
  def link(url: str, title: str = None, type: str = None, description: str = None): # noqa: A002,VNE003
@@ -0,0 +1,8 @@
1
+ class TestLayers:
2
+ E2E = "E2E"
3
+ UI = "UI"
4
+ API = "API"
5
+ CONTRACT = "Contract"
6
+ INTEGRATION = "Integration"
7
+ COMPONENT = "Component"
8
+ UNIT = "Unit"
@@ -33,6 +33,7 @@ class TestResult:
33
33
  __properties: dict = {}
34
34
  __automatic_creation_test_cases: bool = False
35
35
  __external_key: str = None
36
+ __layer: str = None
36
37
 
37
38
  @adapter_logger
38
39
  def set_external_id(self, external_id: str):
@@ -295,3 +296,13 @@ class TestResult:
295
296
  @adapter_logger
296
297
  def get_external_key(self) -> str:
297
298
  return self.__external_key
299
+
300
+ @adapter_logger
301
+ def set_layer(self, layer: str):
302
+ self.__layer = HtmlEscapeUtils.escape_html_tags(layer) if layer else None
303
+
304
+ return self
305
+
306
+ @adapter_logger
307
+ def get_layer(self) -> str:
308
+ return self.__layer
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: testit-python-commons
3
- Version: 5.1.6
3
+ Version: 5.2.0
4
4
  Summary: Python commons for Test IT
5
5
  Home-page: https://github.com/testit-tms/adapters-python/
6
6
  Author: Integration team
@@ -1,4 +1,4 @@
1
- testit.py,sha256=DfWIpqiZdbZV86cKB15RrhP1orXoJA0iwVygrsdzJJk,1196
1
+ testit.py,sha256=C5BsPRgKaquGB656kuE75QWEhSqBjGSZfNYBzPnBofo,1303
2
2
  adapters_api/__init__.py,sha256=fqW8APi58KZ76csM-f1XP1XAgfzMFQuIMQ6F2EBo9xE,749
3
3
  adapters_api/api_client.py,sha256=eBdekkUzczBxt3aZL6VcnU4L70LV_Fk0wPFGWmQQNyo,39263
4
4
  adapters_api/configuration.py,sha256=JZv-bDb_CNGYjNpIvydnCxlyTcE119bjM02dixGcZI4,17594
@@ -87,7 +87,7 @@ adapters_api/model/create_parameter_api_model.py,sha256=P3G0YgYNU5_hLq89M5sLEPtS
87
87
  adapters_api/model/create_project_api_model.py,sha256=coF93QOv0K4K7VXmSGJ-JiOBZ5fNCIg19sUtc4OlhaA,12299
88
88
  adapters_api/model/create_step_api_model.py,sha256=svxMCm-uYh84unidaQJCObnU2EmbFk89GSCWjQCXnMg,12443
89
89
  adapters_api/model/create_work_item_api_model.py,sha256=EzmrvvY9i0pa16pOi8CBSCLggWqJhoaaIApV3KwRb_k,19325
90
- adapters_api/model/custom_attribute_api_result.py,sha256=dLcFxc_TjGd07NMAPH-6KBK8MSt6JpRGkGFm8Jef3T0,15741
90
+ adapters_api/model/custom_attribute_api_result.py,sha256=1Pw5iR6D1PjIUqPMVBdfOKiXyFmDO7oB0qyY8_zWbB4,15484
91
91
  adapters_api/model/custom_attribute_model.py,sha256=VY_-fSRrKS9sOypqeIyqGgA_DtJa2Pljni3UQ1jEj2M,15441
92
92
  adapters_api/model/custom_attribute_option_api_result.py,sha256=lDAUHMB6PldxCZhW2ACspGT9IGaJ__B4Uum2sGq2-I0,12278
93
93
  adapters_api/model/custom_attribute_option_model.py,sha256=URb2QQ50eW37AxVYLvtWmaP0MQP_UWr8JHz-fAIS5ok,12360
@@ -116,7 +116,7 @@ adapters_api/model/label_api_result.py,sha256=4pkd7qYkZDCtIcGY2JFt3YapmivhXsPpF8
116
116
  adapters_api/model/label_short_model.py,sha256=cB-9ama3YfjicX_zHKGPHTVZyg2MdSbHoozpFoPx1QA,11582
117
117
  adapters_api/model/layer_api_model.py,sha256=qYmMqRrSO8eWwfjBdjmIPBhr8TE_U6zz9XWPwNXDDtA,11877
118
118
  adapters_api/model/layer_api_result.py,sha256=mObZqHFPXWAPmkKmI6foOuWTVje46XGsY_VSTuIY2sk,11637
119
- adapters_api/model/layer_source.py,sha256=W-1Xs4vVGXxwle9rrTgPwJHRXH5bJslBuKL2ArxQEd8,11977
119
+ adapters_api/model/layer_source.py,sha256=f30HM5goU76BYNh41_cuZAr7H1r2HgOxpIANnP5RC6k,12049
120
120
  adapters_api/model/link_api_result.py,sha256=gxAliGWvYBxyLJegMvrt8Grjm08h4Zb3kqeIuQonfHY,12441
121
121
  adapters_api/model/link_create_api_model.py,sha256=Rc-uaabycSDwdtruWTngzFYcYFuI20ERguKbK7sGzfY,12267
122
122
  adapters_api/model/link_model.py,sha256=cbs-DTNn2exDlN6xKpwY2xbZ8did5I7uqXpK2H_GDaE,12677
@@ -223,13 +223,13 @@ api_client_syncstorage/model/test_result_save_response.py,sha256=Q7J6WD6Yzx6TWYO
223
223
  api_client_syncstorage/models/__init__.py,sha256=-Wa3--s7VgbP9o6_RY33g1lXm5J-1PSqLw7VcpPZsaY,1131
224
224
  testit_python_commons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
225
225
  testit_python_commons/app_properties.py,sha256=0o7G24OMdcyv7eZUAaZjyvuEp1z9QVVlnDMIra-wXQQ,9891
226
- testit_python_commons/decorators.py,sha256=QI8qMjDincTRZmcZByP5y5wHsf_Fwd1oc67WuWAacCA,5988
226
+ testit_python_commons/decorators.py,sha256=5P0VF1z0rncMiB-G_eeuj536vizYj2UQVDroXYzAYXA,6224
227
227
  testit_python_commons/dynamic_methods.py,sha256=WKHHA6Uj61tWXI3DphALYOi2BV6TnQKvQy0-Vt2JR2I,8816
228
228
  testit_python_commons/step.py,sha256=CYUs_S8opmRg1tsTY1dVJOPzzt-HYR3_uLTBpYtHSfQ,3244
229
229
  testit_python_commons/client/__init__.py,sha256=zSJhxDHzWWTFHJ0s8bqCaBtM5FK2GcPgZxaKdI8zf-o,165
230
230
  testit_python_commons/client/api_client.py,sha256=SgIPi9AG8o5jAATggZeiUvK7Hffuir_Z7727AJT3OEs,25274
231
231
  testit_python_commons/client/client_configuration.py,sha256=1M-OrROU3Xj0YGsUX4venG-l6Ewr43LNvUcyFfY57ys,2776
232
- testit_python_commons/client/converter.py,sha256=eZ0GR6DaAdrQeTzKpzGYLPEcGbkc7lTwiVwKGn6cPxE,26998
232
+ testit_python_commons/client/converter.py,sha256=QJ-zRG7-DuXx6c_ujLIjlOT6kfBRqLh196Xt9_eo8RU,28147
233
233
  testit_python_commons/client/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
234
234
  testit_python_commons/client/helpers/bulk_autotest_helper.py,sha256=k_5sK3tVz0fCZw_Eh2mk9diHF_bLin0P4016E2gWQQI,10888
235
235
  testit_python_commons/client/helpers/test_result_matching.py,sha256=XSGzzESs-vg41MrvcijD91snpczL3fiVTywOe2j2WZg,1373
@@ -247,7 +247,8 @@ testit_python_commons/models/link_type.py,sha256=n5XaVXu4s2KQDp9vPaO10wRKSfm4NlA
247
247
  testit_python_commons/models/outcome_type.py,sha256=WAAuPRTopmYPczd-Gd0IrE7SGDZOIZKFDwxkywVrTJM,111
248
248
  testit_python_commons/models/status_type.py,sha256=lm4Hp02Z5Wo1mOaaMDjzBD1W0BE6gtwjBMPdhxuO_5U,152
249
249
  testit_python_commons/models/step_result.py,sha256=T9BbcPB6BCz3ZkrWXy2Z2Guj2wecvKJX1oIrG-yJH4I,2209
250
- testit_python_commons/models/test_result.py,sha256=z6OB3V_whCQDJvr4jQdgVanoJSoeKh8ZXgPAACkNrdw,7515
250
+ testit_python_commons/models/test_layers.py,sha256=XACHq-r3bf35ktU9_HUputiBYKXwOXJmeqMJTnrB460,168
251
+ testit_python_commons/models/test_result.py,sha256=R2CaQFnHVH_grf0LIvat7Dq1PlPCJm_-kbAkot8ANwg,7781
251
252
  testit_python_commons/models/test_result_with_all_fixture_step_results_model.py,sha256=aI5nfJ_4EAhzZg7eIV1JhSf9i3EENiRiuQuqJvSUs3M,866
252
253
  testit_python_commons/services/__init__.py,sha256=yVVmiCgMyike_8OoNPiHLNoMqKhCDlWYhvmGW0IRHJM,1197
253
254
  testit_python_commons/services/adapter_manager.py,sha256=UJK0c8aj4X2UI8rFNR2wYtPnHWDOA8c5K0dAQeDOIRU,11849
@@ -265,7 +266,7 @@ testit_python_commons/services/sync_storage/__init__.py,sha256=Qmjs6Xk5l-i5FFItk
265
266
  testit_python_commons/services/sync_storage/sync_storage_runner.py,sha256=DPOHJZ57otKlmAHHD7JV1rfYAgSTm0fYTvlp1QFtR4I,20539
266
267
  testit_python_commons/utils/__init__.py,sha256=CUHziylwvFAuKyUM1tCp13ik5Z2Mw-VK8n7c92aVy-I,78
267
268
  testit_python_commons/utils/html_escape_utils.py,sha256=wx20lAVrMvhNiQ7bEu_f-SGqDBp85D-EBL2sgTmnJPY,8135
268
- testit_python_commons-5.1.6.dist-info/METADATA,sha256=v4geoQxyK1YoCKY725v_iP2DQEsTwQo5jy4cwoJNOZQ,1766
269
- testit_python_commons-5.1.6.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
270
- testit_python_commons-5.1.6.dist-info/top_level.txt,sha256=TuyfRneOyFuvNz83bbn-pWaAR1fY7FINrrJRTW9Lyqg,65
271
- testit_python_commons-5.1.6.dist-info/RECORD,,
269
+ testit_python_commons-5.2.0.dist-info/METADATA,sha256=_bZbHygVpktiVYN0yafMebpPJudr0lBMzx9x1Vdo9ZQ,1766
270
+ testit_python_commons-5.2.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
271
+ testit_python_commons-5.2.0.dist-info/top_level.txt,sha256=TuyfRneOyFuvNz83bbn-pWaAR1fY7FINrrJRTW9Lyqg,65
272
+ testit_python_commons-5.2.0.dist-info/RECORD,,