datamodel-code-generator 0.27.2__py3-none-any.whl → 0.28.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.

Potentially problematic release.


This version of datamodel-code-generator might be problematic. Click here for more details.

Files changed (43) hide show
  1. datamodel_code_generator/__init__.py +168 -196
  2. datamodel_code_generator/__main__.py +146 -189
  3. datamodel_code_generator/arguments.py +227 -230
  4. datamodel_code_generator/format.py +77 -129
  5. datamodel_code_generator/http.py +12 -10
  6. datamodel_code_generator/imports.py +59 -65
  7. datamodel_code_generator/model/__init__.py +28 -31
  8. datamodel_code_generator/model/base.py +100 -144
  9. datamodel_code_generator/model/dataclass.py +62 -70
  10. datamodel_code_generator/model/enum.py +34 -30
  11. datamodel_code_generator/model/imports.py +13 -11
  12. datamodel_code_generator/model/msgspec.py +116 -138
  13. datamodel_code_generator/model/pydantic/__init__.py +18 -28
  14. datamodel_code_generator/model/pydantic/base_model.py +121 -140
  15. datamodel_code_generator/model/pydantic/custom_root_type.py +2 -2
  16. datamodel_code_generator/model/pydantic/dataclass.py +6 -4
  17. datamodel_code_generator/model/pydantic/imports.py +35 -33
  18. datamodel_code_generator/model/pydantic/types.py +91 -119
  19. datamodel_code_generator/model/pydantic_v2/__init__.py +21 -18
  20. datamodel_code_generator/model/pydantic_v2/base_model.py +118 -127
  21. datamodel_code_generator/model/pydantic_v2/imports.py +5 -3
  22. datamodel_code_generator/model/pydantic_v2/root_model.py +6 -6
  23. datamodel_code_generator/model/pydantic_v2/types.py +11 -7
  24. datamodel_code_generator/model/rootmodel.py +1 -1
  25. datamodel_code_generator/model/scalar.py +33 -32
  26. datamodel_code_generator/model/typed_dict.py +41 -51
  27. datamodel_code_generator/model/types.py +24 -19
  28. datamodel_code_generator/model/union.py +21 -17
  29. datamodel_code_generator/parser/__init__.py +16 -12
  30. datamodel_code_generator/parser/base.py +327 -515
  31. datamodel_code_generator/parser/graphql.py +87 -119
  32. datamodel_code_generator/parser/jsonschema.py +438 -607
  33. datamodel_code_generator/parser/openapi.py +180 -220
  34. datamodel_code_generator/pydantic_patch.py +8 -9
  35. datamodel_code_generator/reference.py +199 -297
  36. datamodel_code_generator/types.py +149 -215
  37. datamodel_code_generator/util.py +23 -36
  38. {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/METADATA +10 -5
  39. datamodel_code_generator-0.28.0.dist-info/RECORD +59 -0
  40. datamodel_code_generator-0.27.2.dist-info/RECORD +0 -59
  41. {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/WHEEL +0 -0
  42. {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/entry_points.txt +0 -0
  43. {datamodel_code_generator-0.27.2.dist-info → datamodel_code_generator-0.28.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,3 @@
1
- #! /usr/bin/env python
2
-
3
1
  """
4
2
  Main function.
5
3
  """
@@ -11,30 +9,17 @@ import signal
11
9
  import sys
12
10
  import warnings
13
11
  from collections import defaultdict
12
+ from collections.abc import Sequence # noqa: TC003 # pydantic needs it
14
13
  from enum import IntEnum
15
14
  from io import TextIOBase
16
15
  from pathlib import Path
17
- from typing import (
18
- TYPE_CHECKING,
19
- Any,
20
- DefaultDict,
21
- Dict,
22
- List,
23
- Optional,
24
- Sequence,
25
- Set,
26
- Tuple,
27
- Union,
28
- cast,
29
- )
16
+ from typing import TYPE_CHECKING, Any, Optional, Union, cast
30
17
  from urllib.parse import ParseResult, urlparse
31
18
 
32
19
  import argcomplete
33
20
  import black
34
21
  from pydantic import BaseModel
35
22
 
36
- from datamodel_code_generator.model.pydantic_v2 import UnionMode
37
-
38
23
  if TYPE_CHECKING:
39
24
  from argparse import Namespace
40
25
 
@@ -53,11 +38,13 @@ from datamodel_code_generator.arguments import DEFAULT_ENCODING, arg_parser, nam
53
38
  from datamodel_code_generator.format import (
54
39
  DatetimeClassType,
55
40
  PythonVersion,
41
+ PythonVersionMin,
56
42
  is_supported_in_black,
57
43
  )
58
- from datamodel_code_generator.parser import LiteralType
44
+ from datamodel_code_generator.model.pydantic_v2 import UnionMode # noqa: TC001 # needed for pydantic
45
+ from datamodel_code_generator.parser import LiteralType # noqa: TC001 # needed for pydantic
59
46
  from datamodel_code_generator.reference import is_url
60
- from datamodel_code_generator.types import StrictTypes
47
+ from datamodel_code_generator.types import StrictTypes # noqa: TC001 # needed for pydantic
61
48
  from datamodel_code_generator.util import (
62
49
  PYDANTIC_V2,
63
50
  ConfigDict,
@@ -77,7 +64,7 @@ class Exit(IntEnum):
77
64
 
78
65
 
79
66
  def sig_int_handler(_: int, __: Any) -> None: # pragma: no cover
80
- exit(Exit.OK)
67
+ sys.exit(Exit.OK)
81
68
 
82
69
 
83
70
  signal.signal(signal.SIGINT, sig_int_handler)
@@ -85,7 +72,7 @@ signal.signal(signal.SIGINT, sig_int_handler)
85
72
 
86
73
  class Config(BaseModel):
87
74
  if PYDANTIC_V2:
88
- model_config = ConfigDict(arbitrary_types_allowed=True) # pyright: ignore [reportAssignmentType]
75
+ model_config = ConfigDict(arbitrary_types_allowed=True) # pyright: ignore[reportAssignmentType]
89
76
 
90
77
  def get(self, item: str) -> Any:
91
78
  return getattr(self, item)
@@ -96,7 +83,7 @@ class Config(BaseModel):
96
83
  if TYPE_CHECKING:
97
84
 
98
85
  @classmethod
99
- def get_fields(cls) -> Dict[str, Any]: ...
86
+ def get_fields(cls) -> dict[str, Any]: ...
100
87
 
101
88
  else:
102
89
 
@@ -105,164 +92,140 @@ class Config(BaseModel):
105
92
  return cls.model_validate(obj)
106
93
 
107
94
  @classmethod
108
- def get_fields(cls) -> Dict[str, Any]:
95
+ def get_fields(cls) -> dict[str, Any]:
109
96
  return cls.model_fields
110
97
 
111
98
  else:
112
99
 
113
100
  class Config:
114
- # validate_assignment = True
115
101
  # Pydantic 1.5.1 doesn't support validate_assignment correctly
116
102
  arbitrary_types_allowed = (TextIOBase,)
117
103
 
118
104
  if not TYPE_CHECKING:
119
105
 
120
106
  @classmethod
121
- def get_fields(cls) -> Dict[str, Any]:
107
+ def get_fields(cls) -> dict[str, Any]:
122
108
  return cls.__fields__
123
109
 
124
- @field_validator(
125
- 'aliases', 'extra_template_data', 'custom_formatters_kwargs', mode='before'
126
- )
127
- def validate_file(cls, value: Any) -> Optional[TextIOBase]:
110
+ @field_validator("aliases", "extra_template_data", "custom_formatters_kwargs", mode="before")
111
+ def validate_file(cls, value: Any) -> TextIOBase | None: # noqa: N805
128
112
  if value is None or isinstance(value, TextIOBase):
129
113
  return value
130
- return cast(TextIOBase, Path(value).expanduser().resolve().open('rt'))
114
+ return cast("TextIOBase", Path(value).expanduser().resolve().open("rt"))
131
115
 
132
116
  @field_validator(
133
- 'input',
134
- 'output',
135
- 'custom_template_dir',
136
- 'custom_file_header_path',
137
- mode='before',
117
+ "input",
118
+ "output",
119
+ "custom_template_dir",
120
+ "custom_file_header_path",
121
+ mode="before",
138
122
  )
139
- def validate_path(cls, value: Any) -> Optional[Path]:
123
+ def validate_path(cls, value: Any) -> Path | None: # noqa: N805
140
124
  if value is None or isinstance(value, Path):
141
125
  return value # pragma: no cover
142
126
  return Path(value).expanduser().resolve()
143
127
 
144
- @field_validator('url', mode='before')
145
- def validate_url(cls, value: Any) -> Optional[ParseResult]:
128
+ @field_validator("url", mode="before")
129
+ def validate_url(cls, value: Any) -> ParseResult | None: # noqa: N805
146
130
  if isinstance(value, str) and is_url(value): # pragma: no cover
147
131
  return urlparse(value)
148
- elif value is None: # pragma: no cover
132
+ if value is None: # pragma: no cover
149
133
  return None
150
- raise Error(
151
- f"This protocol doesn't support only http/https. --input={value}"
152
- ) # pragma: no cover
153
-
154
- @model_validator(mode='after')
155
- def validate_use_generic_container_types(
156
- cls, values: Dict[str, Any]
157
- ) -> Dict[str, Any]:
158
- if values.get('use_generic_container_types'):
159
- target_python_version: PythonVersion = values['target_python_version']
160
- if target_python_version == target_python_version.PY_36:
161
- raise Error(
162
- f'`--use-generic-container-types` can not be used with `--target-python-version` {target_python_version.PY_36.value}.\n'
163
- ' The version will be not supported in a future version'
164
- )
134
+ msg = f"This protocol doesn't support only http/https. --input={value}"
135
+ raise Error(msg) # pragma: no cover
136
+
137
+ @model_validator()
138
+ def validate_original_field_name_delimiter(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
139
+ if values.get("original_field_name_delimiter") is not None and not values.get("snake_case_field"):
140
+ msg = "`--original-field-name-delimiter` can not be used without `--snake-case-field`."
141
+ raise Error(msg)
165
142
  return values
166
143
 
167
- @model_validator(mode='after')
168
- def validate_original_field_name_delimiter(
169
- cls, values: Dict[str, Any]
170
- ) -> Dict[str, Any]:
171
- if values.get('original_field_name_delimiter') is not None:
172
- if not values.get('snake_case_field'):
173
- raise Error(
174
- '`--original-field-name-delimiter` can not be used without `--snake-case-field`.'
175
- )
144
+ @model_validator()
145
+ def validate_custom_file_header(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
146
+ if values.get("custom_file_header") and values.get("custom_file_header_path"):
147
+ msg = "`--custom_file_header_path` can not be used with `--custom_file_header`."
148
+ raise Error(msg) # pragma: no cover
176
149
  return values
177
150
 
178
- @model_validator(mode='after')
179
- def validate_custom_file_header(cls, values: Dict[str, Any]) -> Dict[str, Any]:
180
- if values.get('custom_file_header') and values.get('custom_file_header_path'):
181
- raise Error(
182
- '`--custom_file_header_path` can not be used with `--custom_file_header`.'
183
- ) # pragma: no cover
184
- return values
185
-
186
- @model_validator(mode='after')
187
- def validate_keyword_only(cls, values: Dict[str, Any]) -> Dict[str, Any]:
188
- output_model_type: DataModelType = values.get('output_model_type') # pyright: ignore [reportAssignmentType]
189
- python_target: PythonVersion = values.get('target_python_version') # pyright: ignore [reportAssignmentType]
151
+ @model_validator()
152
+ def validate_keyword_only(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
153
+ output_model_type: DataModelType = values.get("output_model_type") # pyright: ignore[reportAssignmentType]
154
+ python_target: PythonVersion = values.get("target_python_version") # pyright: ignore[reportAssignmentType]
190
155
  if (
191
- values.get('keyword_only')
156
+ values.get("keyword_only")
192
157
  and output_model_type == DataModelType.DataclassesDataclass
193
158
  and not python_target.has_kw_only_dataclass
194
159
  ):
195
- raise Error(
196
- f'`--keyword-only` requires `--target-python-version` {PythonVersion.PY_310.value} or higher.'
197
- )
160
+ msg = f"`--keyword-only` requires `--target-python-version` {PythonVersion.PY_310.value} or higher."
161
+ raise Error(msg)
198
162
  return values
199
163
 
200
- @model_validator(mode='after')
201
- def validate_output_datetime_class(cls, values: Dict[str, Any]) -> Dict[str, Any]:
202
- datetime_class_type: Optional[DatetimeClassType] = values.get(
203
- 'output_datetime_class'
204
- )
164
+ @model_validator()
165
+ def validate_output_datetime_class(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
166
+ datetime_class_type: DatetimeClassType | None = values.get("output_datetime_class")
205
167
  if (
206
168
  datetime_class_type
207
169
  and datetime_class_type is not DatetimeClassType.Datetime
208
- and values.get('output_model_type') == DataModelType.DataclassesDataclass
170
+ and values.get("output_model_type") == DataModelType.DataclassesDataclass
209
171
  ):
210
- raise Error(
172
+ msg = (
211
173
  '`--output-datetime-class` only allows "datetime" for '
212
- f'`--output-model-type` {DataModelType.DataclassesDataclass.value}'
174
+ f"`--output-model-type` {DataModelType.DataclassesDataclass.value}"
213
175
  )
176
+ raise Error(msg)
214
177
  return values
215
178
 
216
179
  # Pydantic 1.5.1 doesn't support each_item=True correctly
217
- @field_validator('http_headers', mode='before')
218
- def validate_http_headers(cls, value: Any) -> Optional[List[Tuple[str, str]]]:
219
- def validate_each_item(each_item: Any) -> Tuple[str, str]:
180
+ @field_validator("http_headers", mode="before")
181
+ def validate_http_headers(cls, value: Any) -> list[tuple[str, str]] | None: # noqa: N805
182
+ def validate_each_item(each_item: Any) -> tuple[str, str]:
220
183
  if isinstance(each_item, str): # pragma: no cover
221
184
  try:
222
- field_name, field_value = each_item.split(':', maxsplit=1)
185
+ field_name, field_value = each_item.split(":", maxsplit=1)
223
186
  return field_name, field_value.lstrip()
224
- except ValueError:
225
- raise Error(f'Invalid http header: {each_item!r}')
187
+ except ValueError as exc:
188
+ msg = f"Invalid http header: {each_item!r}"
189
+ raise Error(msg) from exc
226
190
  return each_item # pragma: no cover
227
191
 
228
192
  if isinstance(value, list):
229
193
  return [validate_each_item(each_item) for each_item in value]
230
194
  return value # pragma: no cover
231
195
 
232
- @field_validator('http_query_parameters', mode='before')
233
- def validate_http_query_parameters(
234
- cls, value: Any
235
- ) -> Optional[List[Tuple[str, str]]]:
236
- def validate_each_item(each_item: Any) -> Tuple[str, str]:
196
+ @field_validator("http_query_parameters", mode="before")
197
+ def validate_http_query_parameters(cls, value: Any) -> list[tuple[str, str]] | None: # noqa: N805
198
+ def validate_each_item(each_item: Any) -> tuple[str, str]:
237
199
  if isinstance(each_item, str): # pragma: no cover
238
200
  try:
239
- field_name, field_value = each_item.split('=', maxsplit=1)
201
+ field_name, field_value = each_item.split("=", maxsplit=1)
240
202
  return field_name, field_value.lstrip()
241
- except ValueError:
242
- raise Error(f'Invalid http query parameter: {each_item!r}')
203
+ except ValueError as exc:
204
+ msg = f"Invalid http query parameter: {each_item!r}"
205
+ raise Error(msg) from exc
243
206
  return each_item # pragma: no cover
244
207
 
245
208
  if isinstance(value, list):
246
209
  return [validate_each_item(each_item) for each_item in value]
247
210
  return value # pragma: no cover
248
211
 
249
- @model_validator(mode='before')
250
- def validate_additional_imports(cls, values: Dict[str, Any]) -> Dict[str, Any]:
251
- additional_imports = values.get('additional_imports')
212
+ @model_validator(mode="before")
213
+ def validate_additional_imports(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
214
+ additional_imports = values.get("additional_imports")
252
215
  if additional_imports is not None:
253
- values['additional_imports'] = additional_imports.split(',')
216
+ values["additional_imports"] = additional_imports.split(",")
254
217
  return values
255
218
 
256
- @model_validator(mode='before')
257
- def validate_custom_formatters(cls, values: Dict[str, Any]) -> Dict[str, Any]:
258
- custom_formatters = values.get('custom_formatters')
219
+ @model_validator(mode="before")
220
+ def validate_custom_formatters(cls, values: dict[str, Any]) -> dict[str, Any]: # noqa: N805
221
+ custom_formatters = values.get("custom_formatters")
259
222
  if custom_formatters is not None:
260
- values['custom_formatters'] = custom_formatters.split(',')
223
+ values["custom_formatters"] = custom_formatters.split(",")
261
224
  return values
262
225
 
263
226
  if PYDANTIC_V2:
264
227
 
265
- @model_validator(mode='after') # type: ignore
228
+ @model_validator() # pyright: ignore[reportArgumentType]
266
229
  def validate_root(self: Self) -> Self:
267
230
  if self.use_annotated:
268
231
  self.field_constraints = True
@@ -270,42 +233,42 @@ class Config(BaseModel):
270
233
 
271
234
  else:
272
235
 
273
- @model_validator(mode='after')
274
- def validate_root(cls, values: Any) -> Any:
275
- if values.get('use_annotated'):
276
- values['field_constraints'] = True
236
+ @model_validator()
237
+ def validate_root(cls, values: Any) -> Any: # noqa: N805
238
+ if values.get("use_annotated"):
239
+ values["field_constraints"] = True
277
240
  return values
278
241
 
279
- input: Optional[Union[Path, str]] = None
242
+ input: Optional[Union[Path, str]] = None # noqa: UP007, UP045
280
243
  input_file_type: InputFileType = InputFileType.Auto
281
244
  output_model_type: DataModelType = DataModelType.PydanticBaseModel
282
- output: Optional[Path] = None
245
+ output: Optional[Path] = None # noqa: UP045
283
246
  debug: bool = False
284
247
  disable_warnings: bool = False
285
- target_python_version: PythonVersion = PythonVersion.PY_38
286
- base_class: str = ''
287
- additional_imports: Optional[List[str]] = None
288
- custom_template_dir: Optional[Path] = None
289
- extra_template_data: Optional[TextIOBase] = None
248
+ target_python_version: PythonVersion = PythonVersionMin
249
+ base_class: str = ""
250
+ additional_imports: Optional[list[str]] = None # noqa: UP045
251
+ custom_template_dir: Optional[Path] = None # noqa: UP045
252
+ extra_template_data: Optional[TextIOBase] = None # noqa: UP045
290
253
  validation: bool = False
291
254
  field_constraints: bool = False
292
255
  snake_case_field: bool = False
293
256
  strip_default_none: bool = False
294
- aliases: Optional[TextIOBase] = None
257
+ aliases: Optional[TextIOBase] = None # noqa: UP045
295
258
  disable_timestamp: bool = False
296
259
  enable_version_header: bool = False
297
260
  allow_population_by_field_name: bool = False
298
261
  allow_extra_fields: bool = False
299
262
  use_default: bool = False
300
263
  force_optional: bool = False
301
- class_name: Optional[str] = None
264
+ class_name: Optional[str] = None # noqa: UP045
302
265
  use_standard_collections: bool = False
303
266
  use_schema_description: bool = False
304
267
  use_field_description: bool = False
305
268
  use_default_kwarg: bool = False
306
269
  reuse_model: bool = False
307
270
  encoding: str = DEFAULT_ENCODING
308
- enum_field_as_literal: Optional[LiteralType] = None
271
+ enum_field_as_literal: Optional[LiteralType] = None # noqa: UP045
309
272
  use_one_literal_as_default: bool = False
310
273
  set_default_enum_member: bool = False
311
274
  use_subclass_enum: bool = False
@@ -313,73 +276,69 @@ class Config(BaseModel):
313
276
  use_generic_container_types: bool = False
314
277
  use_union_operator: bool = False
315
278
  enable_faux_immutability: bool = False
316
- url: Optional[ParseResult] = None
279
+ url: Optional[ParseResult] = None # noqa: UP045
317
280
  disable_appending_item_suffix: bool = False
318
- strict_types: List[StrictTypes] = []
319
- empty_enum_field_name: Optional[str] = None
320
- field_extra_keys: Optional[Set[str]] = None
281
+ strict_types: list[StrictTypes] = []
282
+ empty_enum_field_name: Optional[str] = None # noqa: UP045
283
+ field_extra_keys: Optional[set[str]] = None # noqa: UP045
321
284
  field_include_all_keys: bool = False
322
- field_extra_keys_without_x_prefix: Optional[Set[str]] = None
323
- openapi_scopes: Optional[List[OpenAPIScope]] = [OpenAPIScope.Schemas]
324
- wrap_string_literal: Optional[bool] = None
285
+ field_extra_keys_without_x_prefix: Optional[set[str]] = None # noqa: UP045
286
+ openapi_scopes: Optional[list[OpenAPIScope]] = [OpenAPIScope.Schemas] # noqa: UP045
287
+ wrap_string_literal: Optional[bool] = None # noqa: UP045
325
288
  use_title_as_name: bool = False
326
289
  use_operation_id_as_name: bool = False
327
290
  use_unique_items_as_set: bool = False
328
- http_headers: Optional[Sequence[Tuple[str, str]]] = None
291
+ http_headers: Optional[Sequence[tuple[str, str]]] = None # noqa: UP045
329
292
  http_ignore_tls: bool = False
330
293
  use_annotated: bool = False
331
294
  use_non_positive_negative_number_constrained_types: bool = False
332
- original_field_name_delimiter: Optional[str] = None
295
+ original_field_name_delimiter: Optional[str] = None # noqa: UP045
333
296
  use_double_quotes: bool = False
334
297
  collapse_root_models: bool = False
335
- special_field_name_prefix: Optional[str] = None
298
+ special_field_name_prefix: Optional[str] = None # noqa: UP045
336
299
  remove_special_field_name_prefix: bool = False
337
300
  capitalise_enum_members: bool = False
338
301
  keep_model_order: bool = False
339
- custom_file_header: Optional[str] = None
340
- custom_file_header_path: Optional[Path] = None
341
- custom_formatters: Optional[List[str]] = None
342
- custom_formatters_kwargs: Optional[TextIOBase] = None
302
+ custom_file_header: Optional[str] = None # noqa: UP045
303
+ custom_file_header_path: Optional[Path] = None # noqa: UP045
304
+ custom_formatters: Optional[list[str]] = None # noqa: UP045
305
+ custom_formatters_kwargs: Optional[TextIOBase] = None # noqa: UP045
343
306
  use_pendulum: bool = False
344
- http_query_parameters: Optional[Sequence[Tuple[str, str]]] = None
307
+ http_query_parameters: Optional[Sequence[tuple[str, str]]] = None # noqa: UP045
345
308
  treat_dot_as_module: bool = False
346
309
  use_exact_imports: bool = False
347
- union_mode: Optional[UnionMode] = None
348
- output_datetime_class: Optional[DatetimeClassType] = None
310
+ union_mode: Optional[UnionMode] = None # noqa: UP045
311
+ output_datetime_class: Optional[DatetimeClassType] = None # noqa: UP045
349
312
  keyword_only: bool = False
350
313
  no_alias: bool = False
351
314
 
352
315
  def merge_args(self, args: Namespace) -> None:
353
- set_args = {
354
- f: getattr(args, f)
355
- for f in self.get_fields()
356
- if getattr(args, f) is not None
357
- }
316
+ set_args = {f: getattr(args, f) for f in self.get_fields() if getattr(args, f) is not None}
358
317
 
359
- if set_args.get('output_model_type') == DataModelType.MsgspecStruct.value:
360
- set_args['use_annotated'] = True
318
+ if set_args.get("output_model_type") == DataModelType.MsgspecStruct.value:
319
+ set_args["use_annotated"] = True
361
320
 
362
- if set_args.get('use_annotated'):
363
- set_args['field_constraints'] = True
321
+ if set_args.get("use_annotated"):
322
+ set_args["field_constraints"] = True
364
323
 
365
324
  parsed_args = Config.parse_obj(set_args)
366
325
  for field_name in set_args:
367
326
  setattr(self, field_name, getattr(parsed_args, field_name))
368
327
 
369
328
 
370
- def _get_pyproject_toml_config(source: Path) -> Optional[Dict[str, Any]]:
329
+ def _get_pyproject_toml_config(source: Path) -> dict[str, Any] | None:
371
330
  """Find and return the [tool.datamodel-codgen] section of the closest
372
331
  pyproject.toml if it exists.
373
332
  """
374
333
 
375
334
  current_path = source
376
335
  while current_path != current_path.parent:
377
- if (current_path / 'pyproject.toml').is_file():
378
- pyproject_toml = load_toml(current_path / 'pyproject.toml')
379
- if 'datamodel-codegen' in pyproject_toml.get('tool', {}):
380
- return pyproject_toml['tool']['datamodel-codegen']
336
+ if (current_path / "pyproject.toml").is_file():
337
+ pyproject_toml = load_toml(current_path / "pyproject.toml")
338
+ if "datamodel-codegen" in pyproject_toml.get("tool", {}):
339
+ return pyproject_toml["tool"]["datamodel-codegen"]
381
340
 
382
- if (current_path / '.git').exists():
341
+ if (current_path / ".git").exists():
383
342
  # Stop early if we see a git repository root.
384
343
  return None
385
344
 
@@ -387,7 +346,7 @@ def _get_pyproject_toml_config(source: Path) -> Optional[Dict[str, Any]]:
387
346
  return None
388
347
 
389
348
 
390
- def main(args: Optional[Sequence[str]] = None) -> Exit:
349
+ def main(args: Sequence[str] | None = None) -> Exit: # noqa: PLR0911, PLR0912, PLR0915
391
350
  """Main function."""
392
351
 
393
352
  # add cli completion support
@@ -399,14 +358,14 @@ def main(args: Optional[Sequence[str]] = None) -> Exit:
399
358
  arg_parser.parse_args(args, namespace=namespace)
400
359
 
401
360
  if namespace.version:
402
- from datamodel_code_generator import get_version
361
+ from datamodel_code_generator import get_version # noqa: PLC0415
403
362
 
404
- print(get_version())
405
- exit(0)
363
+ print(get_version()) # noqa: T201
364
+ sys.exit(0)
406
365
 
407
- pyproject_config = _get_pyproject_toml_config(Path().resolve())
366
+ pyproject_config = _get_pyproject_toml_config(Path.cwd())
408
367
  if pyproject_config is not None:
409
- pyproject_toml = {k.replace('-', '_'): v for k, v in pyproject_config.items()}
368
+ pyproject_toml = {k.replace("-", "_"): v for k, v in pyproject_config.items()}
410
369
  else:
411
370
  pyproject_toml = {}
412
371
 
@@ -414,22 +373,22 @@ def main(args: Optional[Sequence[str]] = None) -> Exit:
414
373
  config = Config.parse_obj(pyproject_toml)
415
374
  config.merge_args(namespace)
416
375
  except Error as e:
417
- print(e.message, file=sys.stderr)
376
+ print(e.message, file=sys.stderr) # noqa: T201
418
377
  return Exit.ERROR
419
378
 
420
379
  if not config.input and not config.url and sys.stdin.isatty():
421
- print(
422
- 'Not Found Input: require `stdin` or arguments `--input` or `--url`',
380
+ print( # noqa: T201
381
+ "Not Found Input: require `stdin` or arguments `--input` or `--url`",
423
382
  file=sys.stderr,
424
383
  )
425
384
  arg_parser.print_help()
426
385
  return Exit.ERROR
427
386
 
428
387
  if not is_supported_in_black(config.target_python_version): # pragma: no cover
429
- print(
430
- f"Installed black doesn't support Python version {config.target_python_version.value}.\n" # type: ignore
431
- f'You have to install a newer black.\n'
432
- f'Installed black version: {black.__version__}',
388
+ print( # noqa: T201
389
+ f"Installed black doesn't support Python version {config.target_python_version.value}.\n"
390
+ f"You have to install a newer black.\n"
391
+ f"Installed black version: {black.__version__}",
433
392
  file=sys.stderr,
434
393
  )
435
394
  return Exit.ERROR
@@ -438,18 +397,16 @@ def main(args: Optional[Sequence[str]] = None) -> Exit:
438
397
  enable_debug_message()
439
398
 
440
399
  if config.disable_warnings:
441
- warnings.simplefilter('ignore')
442
- extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]]
400
+ warnings.simplefilter("ignore")
401
+ extra_template_data: defaultdict[str, dict[str, Any]] | None
443
402
  if config.extra_template_data is None:
444
403
  extra_template_data = None
445
404
  else:
446
405
  with config.extra_template_data as data:
447
406
  try:
448
- extra_template_data = json.load(
449
- data, object_hook=lambda d: defaultdict(dict, **d)
450
- )
407
+ extra_template_data = json.load(data, object_hook=lambda d: defaultdict(dict, **d))
451
408
  except json.JSONDecodeError as e:
452
- print(f'Unable to load extra template data: {e}', file=sys.stderr)
409
+ print(f"Unable to load extra template data: {e}", file=sys.stderr) # noqa: T201
453
410
  return Exit.ERROR
454
411
 
455
412
  if config.aliases is None:
@@ -459,12 +416,12 @@ def main(args: Optional[Sequence[str]] = None) -> Exit:
459
416
  try:
460
417
  aliases = json.load(data)
461
418
  except json.JSONDecodeError as e:
462
- print(f'Unable to load alias mapping: {e}', file=sys.stderr)
419
+ print(f"Unable to load alias mapping: {e}", file=sys.stderr) # noqa: T201
463
420
  return Exit.ERROR
464
421
  if not isinstance(aliases, dict) or not all(
465
422
  isinstance(k, str) and isinstance(v, str) for k, v in aliases.items()
466
423
  ):
467
- print(
424
+ print( # noqa: T201
468
425
  'Alias mapping must be a JSON string mapping (e.g. {"from": "to", ...})',
469
426
  file=sys.stderr,
470
427
  )
@@ -477,16 +434,15 @@ def main(args: Optional[Sequence[str]] = None) -> Exit:
477
434
  try:
478
435
  custom_formatters_kwargs = json.load(data)
479
436
  except json.JSONDecodeError as e: # pragma: no cover
480
- print(
481
- f'Unable to load custom_formatters_kwargs mapping: {e}',
437
+ print( # noqa: T201
438
+ f"Unable to load custom_formatters_kwargs mapping: {e}",
482
439
  file=sys.stderr,
483
440
  )
484
441
  return Exit.ERROR
485
442
  if not isinstance(custom_formatters_kwargs, dict) or not all(
486
- isinstance(k, str) and isinstance(v, str)
487
- for k, v in custom_formatters_kwargs.items()
443
+ isinstance(k, str) and isinstance(v, str) for k, v in custom_formatters_kwargs.items()
488
444
  ): # pragma: no cover
489
- print(
445
+ print( # noqa: T201
490
446
  'Custom formatters kwargs mapping must be a JSON string mapping (e.g. {"from": "to", ...})',
491
447
  file=sys.stderr,
492
448
  )
@@ -564,19 +520,20 @@ def main(args: Optional[Sequence[str]] = None) -> Exit:
564
520
  keyword_only=config.keyword_only,
565
521
  no_alias=config.no_alias,
566
522
  )
567
- return Exit.OK
568
523
  except InvalidClassNameError as e:
569
- print(f'{e} You have to set `--class-name` option', file=sys.stderr)
524
+ print(f"{e} You have to set `--class-name` option", file=sys.stderr) # noqa: T201
570
525
  return Exit.ERROR
571
526
  except Error as e:
572
- print(str(e), file=sys.stderr)
527
+ print(str(e), file=sys.stderr) # noqa: T201
573
528
  return Exit.ERROR
574
- except Exception:
575
- import traceback
529
+ except Exception: # noqa: BLE001
530
+ import traceback # noqa: PLC0415
576
531
 
577
- print(traceback.format_exc(), file=sys.stderr)
532
+ print(traceback.format_exc(), file=sys.stderr) # noqa: T201
578
533
  return Exit.ERROR
534
+ else:
535
+ return Exit.OK
579
536
 
580
537
 
581
- if __name__ == '__main__':
538
+ if __name__ == "__main__":
582
539
  sys.exit(main())