@autorest/python 5.16.0 → 5.19.0

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.
Files changed (96) hide show
  1. package/ChangeLog.md +79 -4
  2. package/README.md +30 -4
  3. package/autorest/__init__.py +1 -1
  4. package/autorest/codegen/__init__.py +55 -211
  5. package/autorest/codegen/models/__init__.py +116 -83
  6. package/autorest/codegen/models/base_builder.py +49 -88
  7. package/autorest/codegen/models/base_model.py +1 -1
  8. package/autorest/codegen/models/{base_schema.py → base_type.py} +61 -39
  9. package/autorest/codegen/models/client.py +165 -53
  10. package/autorest/codegen/models/code_model.py +122 -257
  11. package/autorest/codegen/models/combined_type.py +107 -0
  12. package/autorest/codegen/models/{constant_schema.py → constant_type.py} +49 -40
  13. package/autorest/codegen/models/credential_types.py +224 -0
  14. package/autorest/codegen/models/dictionary_type.py +131 -0
  15. package/autorest/codegen/models/enum_type.py +195 -0
  16. package/autorest/codegen/models/imports.py +80 -2
  17. package/autorest/codegen/models/list_type.py +149 -0
  18. package/autorest/codegen/models/lro_operation.py +79 -156
  19. package/autorest/codegen/models/lro_paging_operation.py +28 -11
  20. package/autorest/codegen/models/model_type.py +262 -0
  21. package/autorest/codegen/models/operation.py +331 -298
  22. package/autorest/codegen/models/operation_group.py +54 -91
  23. package/autorest/codegen/models/paging_operation.py +82 -123
  24. package/autorest/codegen/models/parameter.py +289 -396
  25. package/autorest/codegen/models/parameter_list.py +355 -360
  26. package/autorest/codegen/models/primitive_types.py +544 -0
  27. package/autorest/codegen/models/property.py +123 -139
  28. package/autorest/codegen/models/request_builder.py +130 -102
  29. package/autorest/codegen/models/request_builder_parameter.py +112 -100
  30. package/autorest/codegen/models/response.py +325 -0
  31. package/autorest/codegen/models/utils.py +12 -19
  32. package/autorest/codegen/serializers/__init__.py +55 -37
  33. package/autorest/codegen/serializers/builder_serializer.py +695 -1144
  34. package/autorest/codegen/serializers/client_serializer.py +92 -89
  35. package/autorest/codegen/serializers/general_serializer.py +15 -69
  36. package/autorest/codegen/serializers/import_serializer.py +7 -4
  37. package/autorest/codegen/serializers/metadata_serializer.py +15 -104
  38. package/autorest/codegen/serializers/model_base_serializer.py +49 -36
  39. package/autorest/codegen/serializers/model_generic_serializer.py +8 -6
  40. package/autorest/codegen/serializers/model_init_serializer.py +2 -4
  41. package/autorest/codegen/serializers/model_python3_serializer.py +22 -16
  42. package/autorest/codegen/serializers/operation_groups_serializer.py +7 -13
  43. package/autorest/codegen/serializers/parameter_serializer.py +174 -0
  44. package/autorest/codegen/serializers/request_builders_serializer.py +13 -30
  45. package/autorest/codegen/serializers/utils.py +0 -140
  46. package/autorest/codegen/templates/MANIFEST.in.jinja2 +1 -0
  47. package/autorest/codegen/templates/{service_client.py.jinja2 → client.py.jinja2} +10 -7
  48. package/autorest/codegen/templates/config.py.jinja2 +13 -13
  49. package/autorest/codegen/templates/enum.py.jinja2 +4 -4
  50. package/autorest/codegen/templates/enum_container.py.jinja2 +1 -1
  51. package/autorest/codegen/templates/init.py.jinja2 +2 -2
  52. package/autorest/codegen/templates/lro_operation.py.jinja2 +4 -1
  53. package/autorest/codegen/templates/lro_paging_operation.py.jinja2 +4 -1
  54. package/autorest/codegen/templates/metadata.json.jinja2 +33 -33
  55. package/autorest/codegen/templates/model.py.jinja2 +23 -24
  56. package/autorest/codegen/templates/model_container.py.jinja2 +2 -1
  57. package/autorest/codegen/templates/model_init.py.jinja2 +3 -5
  58. package/autorest/codegen/templates/operation.py.jinja2 +6 -8
  59. package/autorest/codegen/templates/operation_group.py.jinja2 +21 -8
  60. package/autorest/codegen/templates/operation_groups_container.py.jinja2 +2 -2
  61. package/autorest/codegen/templates/operation_tools.jinja2 +11 -3
  62. package/autorest/codegen/templates/paging_operation.py.jinja2 +2 -2
  63. package/autorest/codegen/templates/request_builder.py.jinja2 +10 -15
  64. package/autorest/codegen/templates/request_builders.py.jinja2 +1 -1
  65. package/autorest/codegen/templates/serialization.py.jinja2 +2006 -0
  66. package/autorest/codegen/templates/setup.py.jinja2 +13 -3
  67. package/autorest/codegen/templates/vendor.py.jinja2 +11 -1
  68. package/autorest/jsonrpc/server.py +15 -3
  69. package/autorest/m4reformatter/__init__.py +1126 -0
  70. package/autorest/multiapi/models/client.py +12 -2
  71. package/autorest/multiapi/models/code_model.py +1 -1
  72. package/autorest/multiapi/serializers/__init__.py +18 -4
  73. package/autorest/multiapi/templates/multiapi_config.py.jinja2 +3 -3
  74. package/autorest/multiapi/templates/multiapi_init.py.jinja2 +2 -2
  75. package/autorest/multiapi/templates/multiapi_operations_mixin.py.jinja2 +4 -4
  76. package/autorest/multiapi/templates/multiapi_service_client.py.jinja2 +9 -9
  77. package/autorest/postprocess/__init__.py +202 -0
  78. package/autorest/postprocess/get_all.py +19 -0
  79. package/autorest/postprocess/venvtools.py +73 -0
  80. package/autorest/preprocess/__init__.py +210 -0
  81. package/autorest/preprocess/helpers.py +54 -0
  82. package/autorest/{namer → preprocess}/python_mappings.py +21 -16
  83. package/package.json +2 -2
  84. package/autorest/codegen/models/credential_model.py +0 -55
  85. package/autorest/codegen/models/credential_schema.py +0 -95
  86. package/autorest/codegen/models/credential_schema_policy.py +0 -73
  87. package/autorest/codegen/models/dictionary_schema.py +0 -106
  88. package/autorest/codegen/models/enum_schema.py +0 -225
  89. package/autorest/codegen/models/list_schema.py +0 -135
  90. package/autorest/codegen/models/object_schema.py +0 -303
  91. package/autorest/codegen/models/primitive_schemas.py +0 -495
  92. package/autorest/codegen/models/request_builder_parameter_list.py +0 -249
  93. package/autorest/codegen/models/schema_request.py +0 -55
  94. package/autorest/codegen/models/schema_response.py +0 -141
  95. package/autorest/namer/__init__.py +0 -23
  96. package/autorest/namer/name_converter.py +0 -509
@@ -1,509 +0,0 @@
1
- # -------------------------------------------------------------------------
2
- # Copyright (c) Microsoft Corporation. All rights reserved.
3
- # Licensed under the MIT License. See License.txt in the project root for
4
- # license information.
5
- # --------------------------------------------------------------------------
6
- import re
7
- import copy
8
- from typing import cast, Any, Dict, List, Match, Optional
9
- from .python_mappings import basic_latin_chars, reserved_words, PadType
10
- from ..codegen.models.utils import JSON_REGEXP
11
-
12
-
13
- def _get_all_values(all_headers: List[Dict[str, Any]]) -> List[str]:
14
- content_types: List[str] = []
15
- for h in all_headers:
16
- if h["schema"]["type"] == "constant":
17
- content_types.append(h["schema"]["value"]["value"])
18
- elif any(
19
- choice_type
20
- for choice_type in ["sealed-choice", "choice"]
21
- if h["schema"]["type"] == choice_type
22
- ):
23
- content_types.extend([choice["value"] for choice in h["schema"]["choices"]])
24
- return content_types
25
-
26
-
27
- def _get_default_value(all_values: List[str]) -> str:
28
- json_values = [v for v in all_values if JSON_REGEXP.match(v)]
29
- if json_values:
30
- if "application/json" in json_values:
31
- return "application/json"
32
- return json_values[0]
33
-
34
- xml_values = [v for v in all_values if "xml" in v]
35
- if xml_values:
36
- if "application/xml" in xml_values:
37
- return "application/xml"
38
- return xml_values[0]
39
- return all_values[0]
40
-
41
-
42
- _M4_HEADER_PARAMETERS = ["content_type", "accept"]
43
-
44
-
45
- class NameConverter:
46
- @staticmethod
47
- def convert_yaml_names(yaml_data: Dict[str, Any]) -> None:
48
- NameConverter._convert_language_default_python_case(yaml_data)
49
- yaml_data["info"]["python_title"] = NameConverter._to_valid_python_name(
50
- name=yaml_data["info"]["title"].replace(" ", ""), convert_name=True
51
- )
52
- yaml_data["info"]["pascal_case_title"] = yaml_data["language"]["default"][
53
- "name"
54
- ]
55
- if yaml_data["info"].get("description"):
56
- if yaml_data["info"]["description"][-1] != ".":
57
- yaml_data["info"]["description"] += "."
58
- else:
59
- yaml_data["info"]["description"] = (
60
- yaml_data["info"]["pascal_case_title"] + "."
61
- )
62
- NameConverter._convert_schemas(yaml_data["schemas"])
63
- NameConverter._convert_operation_groups(
64
- yaml_data["operationGroups"], yaml_data["info"]["pascal_case_title"]
65
- )
66
- if yaml_data.get("globalParameters"):
67
- NameConverter._convert_global_parameters(yaml_data["globalParameters"])
68
-
69
- @staticmethod
70
- def _convert_global_parameters(global_parameters: List[Dict[str, Any]]) -> None:
71
- for global_parameter in global_parameters:
72
- NameConverter._convert_language_default_python_case(global_parameter)
73
-
74
- @staticmethod
75
- def _convert_operation_groups(
76
- operation_groups: List[Dict[str, Any]], code_model_title: str
77
- ) -> None:
78
- for operation_group in operation_groups:
79
- builder_group = copy.deepcopy(operation_group)
80
- NameConverter._convert_language_default_python_case(
81
- operation_group, pad_string=PadType.OperationGroup, convert_name=True
82
- )
83
- operation_group_name = operation_group["language"]["default"]["name"]
84
- if not operation_group_name:
85
- operation_group["language"]["python"]["className"] = (
86
- code_model_title + "OperationsMixin"
87
- )
88
- operation_group["language"]["python"]["name"] = ""
89
- elif operation_group_name == "Operations":
90
- operation_group["language"]["python"][
91
- "className"
92
- ] = operation_group_name
93
- else:
94
- operation_group["language"]["python"]["className"] = (
95
- operation_group_name + "Operations"
96
- )
97
- for operation in operation_group["operations"]:
98
- NameConverter._convert_language_default_python_case(
99
- operation, pad_string=PadType.Method
100
- )
101
- if operation_group_name:
102
- operation["language"]["python"][
103
- "operationGroupName"
104
- ] = operation_group["language"]["python"]["name"].lower()
105
- NameConverter._convert_language_default_python_case(
106
- builder_group,
107
- pad_string=PadType.BuilderGroup,
108
- convert_name=True,
109
- )
110
- operation["language"]["python"]["builderGroupName"] = builder_group[
111
- "language"
112
- ]["python"]["name"].lower()
113
- else:
114
- operation["language"]["python"]["operationGroupName"] = ""
115
- operation["language"]["python"]["builderGroupName"] = ""
116
- for exception in operation.get("exceptions", []):
117
- NameConverter._convert_language_default_python_case(exception)
118
- for parameter in operation.get("parameters", []):
119
- NameConverter._add_multipart_information(parameter, operation)
120
- NameConverter._convert_language_default_python_case(
121
- parameter, pad_string=PadType.Parameter
122
- )
123
- for request in operation.get("requests", []):
124
- NameConverter._convert_language_default_python_case(request)
125
- for parameter in request.get("parameters", []):
126
- NameConverter._add_multipart_information(parameter, request)
127
- NameConverter._convert_language_default_python_case(
128
- parameter, pad_string=PadType.Parameter
129
- )
130
- if (
131
- parameter.get("origin", "")
132
- == "modelerfour:synthesized/content-type"
133
- ):
134
- parameter["required"] = False
135
- NameConverter._handle_m4_header_parameters(
136
- operation.get("requests", [])
137
- )
138
- for response in operation.get("responses", []):
139
- NameConverter._convert_language_default_python_case(response)
140
- if operation.get("extensions"):
141
- NameConverter._convert_extensions(operation)
142
-
143
- @staticmethod
144
- def _handle_m4_header_parameters(requests):
145
- m4_header_params = []
146
- for request in requests:
147
- m4_header_params.extend(
148
- [
149
- p
150
- for p in request.get("parameters", [])
151
- if NameConverter._is_schema_an_m4_header_parameter(
152
- p["language"]["default"]["name"], p
153
- )
154
- ]
155
- )
156
- m4_header_params_to_remove = []
157
- for m4_header in _M4_HEADER_PARAMETERS:
158
- params_of_header = [
159
- p
160
- for p in m4_header_params
161
- if p["language"]["default"]["name"] == m4_header
162
- ]
163
- if len(params_of_header) < 2:
164
- continue
165
- param_schema_to_param = { # if they share the same schema, we don't need to keep both of them in this case
166
- id(param["schema"]): param for param in params_of_header
167
- }
168
- if len(param_schema_to_param) == 1:
169
- # we'll remove the ones that aren't the first
170
- m4_header_params_to_remove.extend([id(p) for p in params_of_header[1:]])
171
- else:
172
- all_values = _get_all_values(params_of_header)
173
- # if one of them is an enum schema, set the default value to constant
174
- param_with_constant_schema = next(
175
- p for p in params_of_header if p["schema"]["type"] == "constant"
176
- )
177
- try:
178
- param_with_enum_schema = next(
179
- p
180
- for p in params_of_header
181
- if p["schema"]["type"] == "sealed-choice"
182
- or p["schema"]["type"] == "choice"
183
- )
184
- except StopIteration:
185
- # this means there's no enum schema
186
- pass
187
- else:
188
- param_with_enum_schema["clientDefaultValue"] = _get_default_value(
189
- all_values
190
- )
191
- # add constant enum schema value into list of possible schema values
192
- constant_schema = param_with_constant_schema["schema"]
193
- constant_choice = {
194
- "language": {
195
- "default": {
196
- "description": constant_schema["language"]["default"][
197
- "description"
198
- ],
199
- "name": constant_schema["language"]["default"]["name"],
200
- },
201
- "python": {
202
- "description": constant_schema["language"]["python"][
203
- "description"
204
- ],
205
- "name": constant_schema["language"]["python"][
206
- "name"
207
- ].upper(),
208
- },
209
- },
210
- "value": constant_schema["value"]["value"],
211
- }
212
- param_with_enum_schema["schema"]["choices"].append(constant_choice)
213
- m4_header_params_to_remove.append(id(param_with_constant_schema))
214
-
215
- for request in requests:
216
- if not request.get("parameters"):
217
- continue
218
- request["parameters"] = [
219
- p
220
- for p in request["parameters"]
221
- if id(p) not in m4_header_params_to_remove
222
- ]
223
-
224
- @staticmethod
225
- def _add_multipart_information(parameter: Dict[str, Any], request: Dict[str, Any]):
226
- multipart = request["protocol"].get("http", {}).get("multipart", False)
227
- if multipart:
228
- if parameter["protocol"]["http"]["in"] == "body":
229
- parameter["language"]["default"]["multipart"] = True
230
- if parameter["language"]["default"]["serializedName"] == "Content-Type":
231
- parameter["schema"]["value"]["value"] = None
232
-
233
- @staticmethod
234
- def _convert_extensions(operation: Dict[str, Any]) -> None:
235
- operation_extensions = operation["extensions"]
236
- if operation_extensions.get("x-ms-pageable"):
237
- operation["extensions"]["pager-sync"] = operation_extensions.get(
238
- "x-python-custom-pager-sync", "azure.core.paging.ItemPaged"
239
- )
240
- operation["extensions"]["pager-async"] = operation_extensions.get(
241
- "x-python-custom-pager-async", "azure.core.async_paging.AsyncItemPaged"
242
- )
243
- if operation_extensions.get("x-ms-long-running-operation"):
244
- # poller
245
- operation["extensions"]["poller-sync"] = operation_extensions.get(
246
- "x-python-custom-poller-sync", "azure.core.polling.LROPoller"
247
- )
248
- operation["extensions"]["poller-async"] = operation_extensions.get(
249
- "x-python-custom-poller-async", "azure.core.polling.AsyncLROPoller"
250
- )
251
-
252
- # polling methods
253
- sync_polling_method_directive = (
254
- "x-python-custom-default-polling-method-sync"
255
- )
256
- operation["extensions"]["default-polling-method-sync"] = {
257
- "azure-arm": operation_extensions.get(
258
- sync_polling_method_directive,
259
- "azure.mgmt.core.polling.arm_polling.ARMPolling",
260
- ),
261
- "data-plane": operation_extensions.get(
262
- sync_polling_method_directive,
263
- "azure.core.polling.base_polling.LROBasePolling",
264
- ),
265
- }
266
- async_polling_method_directive = (
267
- "x-python-custom-default-polling-method-async"
268
- )
269
- operation["extensions"]["default-polling-method-async"] = {
270
- "azure-arm": operation_extensions.get(
271
- async_polling_method_directive,
272
- "azure.mgmt.core.polling.async_arm_polling.AsyncARMPolling",
273
- ),
274
- "data-plane": operation_extensions.get(
275
- async_polling_method_directive,
276
- "azure.core.polling.async_base_polling.AsyncLROBasePolling",
277
- ),
278
- }
279
-
280
- operation["extensions"][
281
- "default-no-polling-method-sync"
282
- ] = "azure.core.polling.NoPolling"
283
- operation["extensions"][
284
- "default-no-polling-method-async"
285
- ] = "azure.core.polling.AsyncNoPolling"
286
- operation["extensions"][
287
- "base-polling-method-sync"
288
- ] = "azure.core.polling.PollingMethod"
289
- operation["extensions"][
290
- "base-polling-method-async"
291
- ] = "azure.core.polling.AsyncPollingMethod"
292
-
293
- @staticmethod
294
- def _convert_schemas(schemas: Dict[str, Any]) -> None:
295
- for enum in schemas.get("sealedChoices", []) + schemas.get("choices", []):
296
- NameConverter._convert_enum_schema(enum)
297
- for obj in schemas.get("objects", []) + schemas.get("groups", []):
298
- NameConverter._convert_object_schema(obj)
299
- for type_list, schema_yamls in schemas.items():
300
- for schema in schema_yamls:
301
- if type_list == "objects":
302
- continue
303
- if type_list in ["arrays", "dictionaries"]:
304
- NameConverter._convert_language_default_python_case(schema)
305
- NameConverter._convert_language_default_python_case(
306
- schema["elementType"]
307
- )
308
- elif type_list == "constants":
309
- NameConverter._convert_language_default_python_case(schema)
310
- NameConverter._convert_language_default_python_case(schema["value"])
311
- NameConverter._convert_language_default_python_case(
312
- schema["valueType"]
313
- )
314
- else:
315
- NameConverter._convert_language_default_python_case(schema)
316
-
317
- @staticmethod
318
- def _convert_enum_schema(schema: Dict[str, Any]) -> None:
319
- NameConverter._convert_language_default_pascal_case(schema)
320
- for choice in schema["choices"]:
321
- NameConverter._convert_language_default_python_case(
322
- choice, pad_string=PadType.Enum, all_upper=True
323
- )
324
-
325
- @staticmethod
326
- def _convert_object_schema(schema: Dict[str, Any]) -> None:
327
- NameConverter._convert_language_default_pascal_case(schema)
328
- schema_description = schema["language"]["python"]["description"]
329
- if not schema_description:
330
- # what is being used for empty ObjectSchema descriptions
331
- schema_description = schema["language"]["python"]["name"]
332
- if schema_description and schema_description[-1] != ".":
333
- schema_description += "."
334
- schema["language"]["python"]["description"] = schema_description
335
- for prop in schema.get("properties", []):
336
- NameConverter._convert_language_default_python_case(
337
- schema=prop, pad_string=PadType.Property
338
- )
339
-
340
- @staticmethod
341
- def _is_schema_an_m4_header_parameter(
342
- schema_name: str, schema: Dict[str, Any]
343
- ) -> bool:
344
- return (
345
- schema_name in _M4_HEADER_PARAMETERS
346
- and schema.get("protocol", {}).get("http", {}).get("in", {}) == "header"
347
- )
348
-
349
- @staticmethod
350
- def _convert_language_default_python_case(
351
- schema: Dict[str, Any],
352
- *,
353
- pad_string: Optional[PadType] = None,
354
- convert_name: bool = False,
355
- all_upper: bool = False,
356
- ) -> None:
357
- if not schema.get("language") or schema["language"].get("python"):
358
- return
359
- schema["language"]["python"] = dict(schema["language"]["default"])
360
- schema_name = schema["language"]["default"]["name"]
361
- schema_python_name = schema["language"]["python"]["name"]
362
-
363
- if not NameConverter._is_schema_an_m4_header_parameter(schema_name, schema):
364
- # only escaping name if it's not a content_type header parameter
365
- schema_python_name = NameConverter._to_valid_python_name(
366
- name=schema_name, pad_string=pad_string, convert_name=convert_name
367
- )
368
- # need to add the lower in case certain words, like LRO, are overriden to
369
- # always return LRO. Without .lower(), for example, begin_lro would be
370
- # begin_LRO
371
- schema["language"]["python"]["name"] = (
372
- schema_python_name.upper() if all_upper else schema_python_name.lower()
373
- )
374
-
375
- schema_description = schema["language"]["default"]["description"].strip()
376
- if (
377
- pad_string == PadType.Method
378
- and not schema_description
379
- and not schema["language"]["default"].get("summary")
380
- ):
381
- schema_description = schema["language"]["python"]["name"]
382
- if schema_description and schema_description[-1] != ".":
383
- schema_description += "."
384
- schema["language"]["python"]["description"] = schema_description
385
-
386
- schema_summary = schema["language"]["python"].get("summary")
387
- if schema_summary:
388
- schema_summary = schema_summary.strip()
389
- if schema_summary[-1] != ".":
390
- schema_summary += "."
391
- schema["language"]["python"]["summary"] = schema_summary
392
-
393
- @staticmethod
394
- def _convert_language_default_pascal_case(schema: Dict[str, Any]) -> None:
395
- if schema["language"].get("python"):
396
- return
397
- schema["language"]["python"] = dict(schema["language"]["default"])
398
-
399
- schema_description = schema["language"]["default"]["description"].strip()
400
-
401
- schema["language"]["python"]["description"] = schema_description
402
-
403
- @staticmethod
404
- def _to_pascal_case(name: str) -> str:
405
- name_list = re.split("[^a-zA-Z\\d]", name)
406
- name_list = [
407
- s[0].upper() + s[1:] if len(s) > 1 else s.upper() for s in name_list
408
- ]
409
- return "".join(name_list)
410
-
411
- @staticmethod
412
- def _to_valid_python_name(
413
- name: str, *, pad_string: Optional[PadType] = None, convert_name: bool = False
414
- ) -> str:
415
- if not name:
416
- return NameConverter._to_python_case(pad_string.value if pad_string else "")
417
- escaped_name = NameConverter._get_escaped_reserved_name(
418
- NameConverter._to_valid_name(name.replace("-", "_"), ["_"]), pad_string
419
- )
420
- if convert_name or name != escaped_name:
421
- return NameConverter._to_python_case(escaped_name)
422
- return escaped_name
423
-
424
- @staticmethod
425
- def _to_python_case(name: str) -> str:
426
- def replace_upper_characters(m: Match[str]) -> str:
427
- match_str = m.group().lower()
428
- if m.start() > 0 and name[m.start() - 1] == "_":
429
- # we are good if a '_' already exists
430
- return match_str
431
- # the first letter should not have _
432
- prefix = "_" if m.start() > 0 else ""
433
-
434
- # we will add an extra _ if there are multiple upper case chars together
435
- next_non_upper_case_char_location = m.start() + len(match_str)
436
- if (
437
- len(match_str) > 2
438
- and len(name) - next_non_upper_case_char_location > 1
439
- and name[next_non_upper_case_char_location].isalpha()
440
- ):
441
-
442
- return (
443
- prefix
444
- + match_str[: len(match_str) - 1]
445
- + "_"
446
- + match_str[len(match_str) - 1]
447
- )
448
-
449
- return prefix + match_str
450
-
451
- return re.sub("[A-Z]+", replace_upper_characters, name)
452
-
453
- @staticmethod
454
- def _get_escaped_reserved_name(
455
- name: str, pad_string: Optional[PadType] = None
456
- ) -> str:
457
- if name is None:
458
- raise ValueError("The value for name can not be None")
459
- try:
460
- # check to see if name is reserved for the type of name we are converting
461
- pad_string = cast(PadType, pad_string)
462
- # there are some private variables, such as grouped parameters
463
- # that are private. We still want to escape them for DPG
464
- name_prefix = ""
465
- if name[0] == "_":
466
- # i am private
467
- name_prefix = "_"
468
- name = name[1:]
469
- if pad_string and name.lower() in reserved_words[pad_string]:
470
- name += pad_string.value
471
- return name_prefix + name
472
- except AttributeError:
473
- raise ValueError(
474
- f"The name {name} is a reserved word and you have not specified a pad string for it."
475
- )
476
-
477
- @staticmethod
478
- def _remove_invalid_characters(name: str, allowed_characters: List[str]) -> str:
479
- name = name.replace("[]", "Sequence")
480
- valid_string = "".join(
481
- [n for n in name if n.isalpha() or n.isdigit() or n in allowed_characters]
482
- )
483
- return valid_string
484
-
485
- @staticmethod
486
- def _to_valid_name(name: str, allowed_characters: List[str]) -> str:
487
- correct_name = NameConverter._remove_invalid_characters(
488
- name, allowed_characters
489
- )
490
-
491
- # here we have an empty string or a string that consists only of invalid characters
492
- if not correct_name or correct_name[0] in basic_latin_chars.keys():
493
- ret_name = ""
494
- for c in name:
495
- if c in basic_latin_chars.keys():
496
- ret_name += basic_latin_chars[c]
497
- else:
498
- ret_name += c
499
- correct_name = NameConverter._remove_invalid_characters(
500
- ret_name, allowed_characters
501
- )
502
-
503
- if not correct_name:
504
- raise ValueError(
505
- "Property name {} cannot be used as an identifier, as it contains only invalid characters.".format(
506
- name
507
- )
508
- )
509
- return correct_name