datamodel-code-generator 0.27.1__py3-none-any.whl → 0.27.3__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 +159 -190
  2. datamodel_code_generator/__main__.py +151 -173
  3. datamodel_code_generator/arguments.py +227 -230
  4. datamodel_code_generator/format.py +77 -99
  5. datamodel_code_generator/http.py +9 -10
  6. datamodel_code_generator/imports.py +57 -64
  7. datamodel_code_generator/model/__init__.py +26 -31
  8. datamodel_code_generator/model/base.py +94 -127
  9. datamodel_code_generator/model/dataclass.py +58 -59
  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 +112 -126
  13. datamodel_code_generator/model/pydantic/__init__.py +14 -27
  14. datamodel_code_generator/model/pydantic/base_model.py +120 -139
  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 +86 -117
  19. datamodel_code_generator/model/pydantic_v2/__init__.py +17 -17
  20. datamodel_code_generator/model/pydantic_v2/base_model.py +118 -119
  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 +8 -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 +42 -41
  27. datamodel_code_generator/model/types.py +19 -17
  28. datamodel_code_generator/model/union.py +21 -17
  29. datamodel_code_generator/parser/__init__.py +12 -11
  30. datamodel_code_generator/parser/base.py +320 -492
  31. datamodel_code_generator/parser/graphql.py +80 -111
  32. datamodel_code_generator/parser/jsonschema.py +422 -580
  33. datamodel_code_generator/parser/openapi.py +175 -204
  34. datamodel_code_generator/pydantic_patch.py +8 -9
  35. datamodel_code_generator/reference.py +192 -274
  36. datamodel_code_generator/types.py +147 -182
  37. datamodel_code_generator/util.py +22 -26
  38. {datamodel_code_generator-0.27.1.dist-info → datamodel_code_generator-0.27.3.dist-info}/METADATA +12 -11
  39. datamodel_code_generator-0.27.3.dist-info/RECORD +59 -0
  40. datamodel_code_generator-0.27.1.dist-info/RECORD +0 -59
  41. {datamodel_code_generator-0.27.1.dist-info → datamodel_code_generator-0.27.3.dist-info}/WHEEL +0 -0
  42. {datamodel_code_generator-0.27.1.dist-info → datamodel_code_generator-0.27.3.dist-info}/entry_points.txt +0 -0
  43. {datamodel_code_generator-0.27.1.dist-info → datamodel_code_generator-0.27.3.dist-info}/licenses/LICENSE +0 -0
@@ -10,7 +10,6 @@ from typing import (
10
10
  Any,
11
11
  Callable,
12
12
  ClassVar,
13
- DefaultDict,
14
13
  Dict,
15
14
  Generator,
16
15
  Iterable,
@@ -20,7 +19,6 @@ from typing import (
20
19
  Optional,
21
20
  Sequence,
22
21
  Set,
23
- Tuple,
24
22
  Type,
25
23
  Union,
26
24
  )
@@ -74,88 +72,84 @@ if PYDANTIC_V2:
74
72
  from datamodel_code_generator.format import DatetimeClassType
75
73
 
76
74
 
77
- def get_model_by_path(
78
- schema: Union[Dict[str, Any], List[Any]], keys: Union[List[str], List[int]]
79
- ) -> Dict[Any, Any]:
80
- model: Union[Dict[Any, Any], List[Any]]
75
+ def get_model_by_path(schema: dict[str, Any] | list[Any], keys: list[str] | list[int]) -> dict[Any, Any]:
76
+ model: dict[Any, Any] | list[Any]
81
77
  if not keys:
82
78
  model = schema
83
79
  elif len(keys) == 1:
84
- if isinstance(schema, dict):
85
- model = schema.get(keys[0], {}) # type: ignore
86
- else: # pragma: no cover
87
- model = schema[int(keys[0])]
80
+ model = schema.get(str(keys[0]), {}) if isinstance(schema, dict) else schema[int(keys[0])]
88
81
  elif isinstance(schema, dict):
89
- model = get_model_by_path(schema[keys[0]], keys[1:]) # type: ignore
82
+ model = get_model_by_path(schema[str(keys[0])], keys[1:])
90
83
  else:
91
84
  model = get_model_by_path(schema[int(keys[0])], keys[1:])
92
85
  if isinstance(model, dict):
93
86
  return model
87
+ msg = f"Does not support json pointer to array. schema={schema}, key={keys}"
94
88
  raise NotImplementedError( # pragma: no cover
95
- f'Does not support json pointer to array. schema={schema}, key={keys}'
89
+ msg
96
90
  )
97
91
 
98
92
 
99
- json_schema_data_formats: Dict[str, Dict[str, Types]] = {
100
- 'integer': {
101
- 'int32': Types.int32,
102
- 'int64': Types.int64,
103
- 'default': Types.integer,
104
- 'date-time': Types.date_time,
105
- 'unix-time': Types.int64,
93
+ json_schema_data_formats: dict[str, dict[str, Types]] = {
94
+ "integer": {
95
+ "int32": Types.int32,
96
+ "int64": Types.int64,
97
+ "default": Types.integer,
98
+ "date-time": Types.date_time,
99
+ "unix-time": Types.int64,
106
100
  },
107
- 'number': {
108
- 'float': Types.float,
109
- 'double': Types.double,
110
- 'decimal': Types.decimal,
111
- 'date-time': Types.date_time,
112
- 'time': Types.time,
113
- 'default': Types.number,
101
+ "number": {
102
+ "float": Types.float,
103
+ "double": Types.double,
104
+ "decimal": Types.decimal,
105
+ "date-time": Types.date_time,
106
+ "time": Types.time,
107
+ "default": Types.number,
114
108
  },
115
- 'string': {
116
- 'default': Types.string,
117
- 'byte': Types.byte, # base64 encoded string
118
- 'binary': Types.binary,
119
- 'date': Types.date,
120
- 'date-time': Types.date_time,
121
- 'duration': Types.timedelta,
122
- 'time': Types.time,
123
- 'password': Types.password,
124
- 'path': Types.path,
125
- 'email': Types.email,
126
- 'idn-email': Types.email,
127
- 'uuid': Types.uuid,
128
- 'uuid1': Types.uuid1,
129
- 'uuid2': Types.uuid2,
130
- 'uuid3': Types.uuid3,
131
- 'uuid4': Types.uuid4,
132
- 'uuid5': Types.uuid5,
133
- 'uri': Types.uri,
134
- 'uri-reference': Types.string,
135
- 'hostname': Types.hostname,
136
- 'ipv4': Types.ipv4,
137
- 'ipv4-network': Types.ipv4_network,
138
- 'ipv6': Types.ipv6,
139
- 'ipv6-network': Types.ipv6_network,
140
- 'decimal': Types.decimal,
141
- 'integer': Types.integer,
109
+ "string": {
110
+ "default": Types.string,
111
+ "byte": Types.byte, # base64 encoded string
112
+ "binary": Types.binary,
113
+ "date": Types.date,
114
+ "date-time": Types.date_time,
115
+ "duration": Types.timedelta,
116
+ "time": Types.time,
117
+ "password": Types.password,
118
+ "path": Types.path,
119
+ "email": Types.email,
120
+ "idn-email": Types.email,
121
+ "uuid": Types.uuid,
122
+ "uuid1": Types.uuid1,
123
+ "uuid2": Types.uuid2,
124
+ "uuid3": Types.uuid3,
125
+ "uuid4": Types.uuid4,
126
+ "uuid5": Types.uuid5,
127
+ "uri": Types.uri,
128
+ "uri-reference": Types.string,
129
+ "hostname": Types.hostname,
130
+ "ipv4": Types.ipv4,
131
+ "ipv4-network": Types.ipv4_network,
132
+ "ipv6": Types.ipv6,
133
+ "ipv6-network": Types.ipv6_network,
134
+ "decimal": Types.decimal,
135
+ "integer": Types.integer,
142
136
  },
143
- 'boolean': {'default': Types.boolean},
144
- 'object': {'default': Types.object},
145
- 'null': {'default': Types.null},
146
- 'array': {'default': Types.array},
137
+ "boolean": {"default": Types.boolean},
138
+ "object": {"default": Types.object},
139
+ "null": {"default": Types.null},
140
+ "array": {"default": Types.array},
147
141
  }
148
142
 
149
143
 
150
144
  class JSONReference(_enum.Enum):
151
- LOCAL = 'LOCAL'
152
- REMOTE = 'REMOTE'
153
- URL = 'URL'
145
+ LOCAL = "LOCAL"
146
+ REMOTE = "REMOTE"
147
+ URL = "URL"
154
148
 
155
149
 
156
150
  class Discriminator(BaseModel):
157
- propertyName: str
158
- mapping: Optional[Dict[str, str]] = None
151
+ propertyName: str # noqa: N815
152
+ mapping: Optional[Dict[str, str]] = None # noqa: UP006, UP045
159
153
 
160
154
 
161
155
  class JsonSchemaObject(BaseModel):
@@ -163,102 +157,102 @@ class JsonSchemaObject(BaseModel):
163
157
  if PYDANTIC_V2:
164
158
 
165
159
  @classmethod
166
- def get_fields(cls) -> Dict[str, Any]:
160
+ def get_fields(cls) -> dict[str, Any]:
167
161
  return cls.model_fields
168
162
 
169
163
  else:
170
164
 
171
165
  @classmethod
172
- def get_fields(cls) -> Dict[str, Any]:
166
+ def get_fields(cls) -> dict[str, Any]:
173
167
  return cls.__fields__
174
168
 
175
169
  @classmethod
176
170
  def model_rebuild(cls) -> None:
177
171
  cls.update_forward_refs()
178
172
 
179
- __constraint_fields__: Set[str] = {
180
- 'exclusiveMinimum',
181
- 'minimum',
182
- 'exclusiveMaximum',
183
- 'maximum',
184
- 'multipleOf',
185
- 'minItems',
186
- 'maxItems',
187
- 'minLength',
188
- 'maxLength',
189
- 'pattern',
190
- 'uniqueItems',
173
+ __constraint_fields__: Set[str] = { # noqa: RUF012, UP006
174
+ "exclusiveMinimum",
175
+ "minimum",
176
+ "exclusiveMaximum",
177
+ "maximum",
178
+ "multipleOf",
179
+ "minItems",
180
+ "maxItems",
181
+ "minLength",
182
+ "maxLength",
183
+ "pattern",
184
+ "uniqueItems",
191
185
  }
192
- __extra_key__: str = SPECIAL_PATH_FORMAT.format('extras')
186
+ __extra_key__: str = SPECIAL_PATH_FORMAT.format("extras")
193
187
 
194
- @model_validator(mode='before')
195
- def validate_exclusive_maximum_and_exclusive_minimum(cls, values: Any) -> Any:
188
+ @model_validator(mode="before")
189
+ def validate_exclusive_maximum_and_exclusive_minimum(cls, values: Any) -> Any: # noqa: N805
196
190
  if not isinstance(values, dict):
197
191
  return values
198
- exclusive_maximum: Union[float, bool, None] = values.get('exclusiveMaximum')
199
- exclusive_minimum: Union[float, bool, None] = values.get('exclusiveMinimum')
192
+ exclusive_maximum: float | bool | None = values.get("exclusiveMaximum")
193
+ exclusive_minimum: float | bool | None = values.get("exclusiveMinimum")
200
194
 
201
195
  if exclusive_maximum is True:
202
- values['exclusiveMaximum'] = values['maximum']
203
- del values['maximum']
196
+ values["exclusiveMaximum"] = values["maximum"]
197
+ del values["maximum"]
204
198
  elif exclusive_maximum is False:
205
- del values['exclusiveMaximum']
199
+ del values["exclusiveMaximum"]
206
200
  if exclusive_minimum is True:
207
- values['exclusiveMinimum'] = values['minimum']
208
- del values['minimum']
201
+ values["exclusiveMinimum"] = values["minimum"]
202
+ del values["minimum"]
209
203
  elif exclusive_minimum is False:
210
- del values['exclusiveMinimum']
204
+ del values["exclusiveMinimum"]
211
205
  return values
212
206
 
213
- @field_validator('ref')
214
- def validate_ref(cls, value: Any) -> Any:
215
- if isinstance(value, str) and '#' in value:
216
- if value.endswith('#/'):
207
+ @field_validator("ref")
208
+ def validate_ref(cls, value: Any) -> Any: # noqa: N805
209
+ if isinstance(value, str) and "#" in value:
210
+ if value.endswith("#/"):
217
211
  return value[:-1]
218
- elif '#/' in value or value[0] == '#' or value[-1] == '#':
212
+ if "#/" in value or value[0] == "#" or value[-1] == "#":
219
213
  return value
220
- return value.replace('#', '#/')
214
+ return value.replace("#", "#/")
221
215
  return value
222
216
 
223
- items: Union[List[JsonSchemaObject], JsonSchemaObject, bool, None] = None
224
- uniqueItems: Optional[bool] = None
225
- type: Union[str, List[str], None] = None
226
- format: Optional[str] = None
227
- pattern: Optional[str] = None
228
- minLength: Optional[int] = None
229
- maxLength: Optional[int] = None
230
- minimum: Optional[UnionIntFloat] = None
231
- maximum: Optional[UnionIntFloat] = None
232
- minItems: Optional[int] = None
233
- maxItems: Optional[int] = None
234
- multipleOf: Optional[float] = None
235
- exclusiveMaximum: Union[float, bool, None] = None
236
- exclusiveMinimum: Union[float, bool, None] = None
237
- additionalProperties: Union[JsonSchemaObject, bool, None] = None
238
- patternProperties: Optional[Dict[str, JsonSchemaObject]] = None
239
- oneOf: List[JsonSchemaObject] = []
240
- anyOf: List[JsonSchemaObject] = []
241
- allOf: List[JsonSchemaObject] = []
242
- enum: List[Any] = []
243
- writeOnly: Optional[bool] = None
244
- readOnly: Optional[bool] = None
245
- properties: Optional[Dict[str, Union[JsonSchemaObject, bool]]] = None
246
- required: List[str] = []
247
- ref: Optional[str] = Field(default=None, alias='$ref')
248
- nullable: Optional[bool] = False
249
- x_enum_varnames: List[str] = Field(default=[], alias='x-enum-varnames')
250
- description: Optional[str] = None
251
- title: Optional[str] = None
217
+ items: Optional[Union[List[JsonSchemaObject], JsonSchemaObject, bool]] = None # noqa: UP006, UP007, UP045
218
+ uniqueItems: Optional[bool] = None # noqa: N815, UP045
219
+ type: Optional[Union[str, List[str]]] = None # noqa: UP006, UP007, UP045
220
+ format: Optional[str] = None # noqa: UP045
221
+ pattern: Optional[str] = None # noqa: UP045
222
+ minLength: Optional[int] = None # noqa: N815,UP045
223
+ maxLength: Optional[int] = None # noqa: N815,UP045
224
+ minimum: Optional[UnionIntFloat] = None # noqa: UP045
225
+ maximum: Optional[UnionIntFloat] = None # noqa: UP045
226
+ minItems: Optional[int] = None # noqa: N815,UP045
227
+ maxItems: Optional[int] = None # noqa: N815,UP045
228
+ multipleOf: Optional[float] = None # noqa: N815, UP045
229
+ exclusiveMaximum: Optional[Union[float, bool]] = None # noqa: N815, UP007, UP045
230
+ exclusiveMinimum: Optional[Union[float, bool]] = None # noqa: N815, UP007, UP045
231
+ additionalProperties: Optional[Union[JsonSchemaObject, bool]] = None # noqa: N815, UP007, UP045
232
+ patternProperties: Optional[Dict[str, JsonSchemaObject]] = None # noqa: N815, UP006, UP045
233
+ oneOf: List[JsonSchemaObject] = [] # noqa: N815, RUF012, UP006
234
+ anyOf: List[JsonSchemaObject] = [] # noqa: N815, RUF012, UP006
235
+ allOf: List[JsonSchemaObject] = [] # noqa: N815, RUF012, UP006
236
+ enum: List[Any] = [] # noqa: RUF012, UP006
237
+ writeOnly: Optional[bool] = None # noqa: N815, UP045
238
+ readOnly: Optional[bool] = None # noqa: N815, UP045
239
+ properties: Optional[Dict[str, Union[JsonSchemaObject, bool]]] = None # noqa: UP006, UP007, UP045
240
+ required: List[str] = [] # noqa: RUF012, UP006
241
+ ref: Optional[str] = Field(default=None, alias="$ref") # noqa: UP045
242
+ nullable: Optional[bool] = False # noqa: UP045
243
+ x_enum_varnames: List[str] = Field(default=[], alias="x-enum-varnames") # noqa: UP006
244
+ description: Optional[str] = None # noqa: UP045
245
+ title: Optional[str] = None # noqa: UP045
252
246
  example: Any = None
253
247
  examples: Any = None
254
248
  default: Any = None
255
- id: Optional[str] = Field(default=None, alias='$id')
256
- custom_type_path: Optional[str] = Field(default=None, alias='customTypePath')
257
- custom_base_path: Optional[str] = Field(default=None, alias='customBasePath')
258
- extras: Dict[str, Any] = Field(alias=__extra_key__, default_factory=dict)
259
- discriminator: Union[Discriminator, str, None] = None
249
+ id: Optional[str] = Field(default=None, alias="$id") # noqa: UP045
250
+ custom_type_path: Optional[str] = Field(default=None, alias="customTypePath") # noqa: UP045
251
+ custom_base_path: Optional[str] = Field(default=None, alias="customBasePath") # noqa: UP045
252
+ extras: Dict[str, Any] = Field(alias=__extra_key__, default_factory=dict) # noqa: UP006
253
+ discriminator: Optional[Union[Discriminator, str]] = None # noqa: UP007, UP045
260
254
  if PYDANTIC_V2:
261
- model_config = ConfigDict( # pyright: ignore [reportPossiblyUnboundVariable]
255
+ model_config = ConfigDict( # pyright: ignore[reportPossiblyUnboundVariable]
262
256
  arbitrary_types_allowed=True,
263
257
  ignored_types=(cached_property,),
264
258
  )
@@ -274,178 +268,171 @@ class JsonSchemaObject(BaseModel):
274
268
  def __init__(self, **data: Any) -> None:
275
269
  super().__init__(**data)
276
270
  self.extras = {k: v for k, v in data.items() if k not in EXCLUDE_FIELD_KEYS}
277
- if 'const' in data.get(self.__extra_key__, {}):
278
- self.extras['const'] = data[self.__extra_key__]['const']
271
+ if "const" in data.get(self.__extra_key__, {}):
272
+ self.extras["const"] = data[self.__extra_key__]["const"]
279
273
 
280
274
  @cached_property
281
275
  def is_object(self) -> bool:
282
- return (
283
- self.properties is not None
284
- or self.type == 'object'
285
- and not self.allOf
286
- and not self.oneOf
287
- and not self.anyOf
288
- and not self.ref
276
+ return self.properties is not None or (
277
+ self.type == "object" and not self.allOf and not self.oneOf and not self.anyOf and not self.ref
289
278
  )
290
279
 
291
280
  @cached_property
292
281
  def is_array(self) -> bool:
293
- return self.items is not None or self.type == 'array'
282
+ return self.items is not None or self.type == "array"
294
283
 
295
284
  @cached_property
296
285
  def ref_object_name(self) -> str: # pragma: no cover
297
- return self.ref.rsplit('/', 1)[-1] # type: ignore
286
+ return (self.ref or "").rsplit("/", 1)[-1]
298
287
 
299
- @field_validator('items', mode='before')
300
- def validate_items(cls, values: Any) -> Any:
288
+ @field_validator("items", mode="before")
289
+ def validate_items(cls, values: Any) -> Any: # noqa: N805
301
290
  # this condition expects empty dict
302
291
  return values or None
303
292
 
304
293
  @cached_property
305
294
  def has_default(self) -> bool:
306
- return 'default' in self.__fields_set__ or 'default_factory' in self.extras
295
+ return "default" in self.__fields_set__ or "default_factory" in self.extras
307
296
 
308
297
  @cached_property
309
298
  def has_constraint(self) -> bool:
310
299
  return bool(self.__constraint_fields__ & self.__fields_set__)
311
300
 
312
301
  @cached_property
313
- def ref_type(self) -> Optional[JSONReference]:
302
+ def ref_type(self) -> JSONReference | None:
314
303
  if self.ref:
315
304
  return get_ref_type(self.ref)
316
305
  return None # pragma: no cover
317
306
 
318
307
  @cached_property
319
308
  def type_has_null(self) -> bool:
320
- return isinstance(self.type, list) and 'null' in self.type
309
+ return isinstance(self.type, list) and "null" in self.type
321
310
 
322
311
 
323
312
  @lru_cache
324
313
  def get_ref_type(ref: str) -> JSONReference:
325
- if ref[0] == '#':
314
+ if ref[0] == "#":
326
315
  return JSONReference.LOCAL
327
- elif is_url(ref):
316
+ if is_url(ref):
328
317
  return JSONReference.URL
329
318
  return JSONReference.REMOTE
330
319
 
331
320
 
332
- def _get_type(type_: str, format__: Optional[str] = None) -> Types:
321
+ def _get_type(type_: str, format__: str | None = None) -> Types:
333
322
  if type_ not in json_schema_data_formats:
334
323
  return Types.any
335
- data_formats: Optional[Types] = json_schema_data_formats[type_].get(
336
- 'default' if format__ is None else format__
337
- )
324
+ data_formats: Types | None = json_schema_data_formats[type_].get("default" if format__ is None else format__)
338
325
  if data_formats is not None:
339
326
  return data_formats
340
327
 
341
- warn(f'format of {format__!r} not understood for {type_!r} - using default')
342
- return json_schema_data_formats[type_]['default']
328
+ warn(f"format of {format__!r} not understood for {type_!r} - using default", stacklevel=2)
329
+ return json_schema_data_formats[type_]["default"]
343
330
 
344
331
 
345
332
  JsonSchemaObject.model_rebuild()
346
333
 
347
- DEFAULT_FIELD_KEYS: Set[str] = {
348
- 'example',
349
- 'examples',
350
- 'description',
351
- 'discriminator',
352
- 'title',
353
- 'const',
354
- 'default_factory',
334
+ DEFAULT_FIELD_KEYS: set[str] = {
335
+ "example",
336
+ "examples",
337
+ "description",
338
+ "discriminator",
339
+ "title",
340
+ "const",
341
+ "default_factory",
355
342
  }
356
343
 
357
- EXCLUDE_FIELD_KEYS_IN_JSON_SCHEMA: Set[str] = {
358
- 'readOnly',
359
- 'writeOnly',
344
+ EXCLUDE_FIELD_KEYS_IN_JSON_SCHEMA: set[str] = {
345
+ "readOnly",
346
+ "writeOnly",
360
347
  }
361
348
 
362
349
  EXCLUDE_FIELD_KEYS = (
363
- set(JsonSchemaObject.get_fields()) # pyright: ignore [reportAttributeAccessIssue]
350
+ set(JsonSchemaObject.get_fields()) # pyright: ignore[reportAttributeAccessIssue]
364
351
  - DEFAULT_FIELD_KEYS
365
352
  - EXCLUDE_FIELD_KEYS_IN_JSON_SCHEMA
366
353
  ) | {
367
- '$id',
368
- '$ref',
354
+ "$id",
355
+ "$ref",
369
356
  JsonSchemaObject.__extra_key__,
370
357
  }
371
358
 
372
359
 
373
- @snooper_to_methods(max_variable_length=None)
360
+ @snooper_to_methods() # noqa: PLR0904
374
361
  class JsonSchemaParser(Parser):
375
- SCHEMA_PATHS: ClassVar[List[str]] = ['#/definitions', '#/$defs']
376
- SCHEMA_OBJECT_TYPE: ClassVar[Type[JsonSchemaObject]] = JsonSchemaObject
362
+ SCHEMA_PATHS: ClassVar[List[str]] = ["#/definitions", "#/$defs"] # noqa: UP006
363
+ SCHEMA_OBJECT_TYPE: ClassVar[Type[JsonSchemaObject]] = JsonSchemaObject # noqa: UP006
377
364
 
378
- def __init__(
365
+ def __init__( # noqa: PLR0913
379
366
  self,
380
- source: Union[str, Path, List[Path], ParseResult],
367
+ source: str | Path | list[Path] | ParseResult,
381
368
  *,
382
- data_model_type: Type[DataModel] = pydantic_model.BaseModel,
383
- data_model_root_type: Type[DataModel] = pydantic_model.CustomRootType,
384
- data_type_manager_type: Type[DataTypeManager] = pydantic_model.DataTypeManager,
385
- data_model_field_type: Type[DataModelFieldBase] = pydantic_model.DataModelField,
386
- base_class: Optional[str] = None,
387
- additional_imports: Optional[List[str]] = None,
388
- custom_template_dir: Optional[Path] = None,
389
- extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
369
+ data_model_type: type[DataModel] = pydantic_model.BaseModel,
370
+ data_model_root_type: type[DataModel] = pydantic_model.CustomRootType,
371
+ data_type_manager_type: type[DataTypeManager] = pydantic_model.DataTypeManager,
372
+ data_model_field_type: type[DataModelFieldBase] = pydantic_model.DataModelField,
373
+ base_class: str | None = None,
374
+ additional_imports: list[str] | None = None,
375
+ custom_template_dir: Path | None = None,
376
+ extra_template_data: defaultdict[str, dict[str, Any]] | None = None,
390
377
  target_python_version: PythonVersion = PythonVersion.PY_38,
391
- dump_resolve_reference_action: Optional[Callable[[Iterable[str]], str]] = None,
378
+ dump_resolve_reference_action: Callable[[Iterable[str]], str] | None = None,
392
379
  validation: bool = False,
393
380
  field_constraints: bool = False,
394
381
  snake_case_field: bool = False,
395
382
  strip_default_none: bool = False,
396
- aliases: Optional[Mapping[str, str]] = None,
383
+ aliases: Mapping[str, str] | None = None,
397
384
  allow_population_by_field_name: bool = False,
398
385
  apply_default_values_for_required_fields: bool = False,
399
386
  allow_extra_fields: bool = False,
400
387
  force_optional_for_required_fields: bool = False,
401
- class_name: Optional[str] = None,
388
+ class_name: str | None = None,
402
389
  use_standard_collections: bool = False,
403
- base_path: Optional[Path] = None,
390
+ base_path: Path | None = None,
404
391
  use_schema_description: bool = False,
405
392
  use_field_description: bool = False,
406
393
  use_default_kwarg: bool = False,
407
394
  reuse_model: bool = False,
408
- encoding: str = 'utf-8',
409
- enum_field_as_literal: Optional[LiteralType] = None,
395
+ encoding: str = "utf-8",
396
+ enum_field_as_literal: LiteralType | None = None,
410
397
  use_one_literal_as_default: bool = False,
411
398
  set_default_enum_member: bool = False,
412
399
  use_subclass_enum: bool = False,
413
400
  strict_nullable: bool = False,
414
401
  use_generic_container_types: bool = False,
415
402
  enable_faux_immutability: bool = False,
416
- remote_text_cache: Optional[DefaultPutDict[str, str]] = None,
403
+ remote_text_cache: DefaultPutDict[str, str] | None = None,
417
404
  disable_appending_item_suffix: bool = False,
418
- strict_types: Optional[Sequence[StrictTypes]] = None,
419
- empty_enum_field_name: Optional[str] = None,
420
- custom_class_name_generator: Optional[Callable[[str], str]] = None,
421
- field_extra_keys: Optional[Set[str]] = None,
405
+ strict_types: Sequence[StrictTypes] | None = None,
406
+ empty_enum_field_name: str | None = None,
407
+ custom_class_name_generator: Callable[[str], str] | None = None,
408
+ field_extra_keys: set[str] | None = None,
422
409
  field_include_all_keys: bool = False,
423
- field_extra_keys_without_x_prefix: Optional[Set[str]] = None,
424
- wrap_string_literal: Optional[bool] = None,
410
+ field_extra_keys_without_x_prefix: set[str] | None = None,
411
+ wrap_string_literal: bool | None = None,
425
412
  use_title_as_name: bool = False,
426
413
  use_operation_id_as_name: bool = False,
427
414
  use_unique_items_as_set: bool = False,
428
- http_headers: Optional[Sequence[Tuple[str, str]]] = None,
415
+ http_headers: Sequence[tuple[str, str]] | None = None,
429
416
  http_ignore_tls: bool = False,
430
417
  use_annotated: bool = False,
431
418
  use_non_positive_negative_number_constrained_types: bool = False,
432
- original_field_name_delimiter: Optional[str] = None,
419
+ original_field_name_delimiter: str | None = None,
433
420
  use_double_quotes: bool = False,
434
421
  use_union_operator: bool = False,
435
422
  allow_responses_without_content: bool = False,
436
423
  collapse_root_models: bool = False,
437
- special_field_name_prefix: Optional[str] = None,
424
+ special_field_name_prefix: str | None = None,
438
425
  remove_special_field_name_prefix: bool = False,
439
426
  capitalise_enum_members: bool = False,
440
427
  keep_model_order: bool = False,
441
- known_third_party: Optional[List[str]] = None,
442
- custom_formatters: Optional[List[str]] = None,
443
- custom_formatters_kwargs: Optional[Dict[str, Any]] = None,
428
+ known_third_party: list[str] | None = None,
429
+ custom_formatters: list[str] | None = None,
430
+ custom_formatters_kwargs: dict[str, Any] | None = None,
444
431
  use_pendulum: bool = False,
445
- http_query_parameters: Optional[Sequence[Tuple[str, str]]] = None,
432
+ http_query_parameters: Sequence[tuple[str, str]] | None = None,
446
433
  treat_dots_as_module: bool = False,
447
434
  use_exact_imports: bool = False,
448
- default_field_extras: Optional[Dict[str, Any]] = None,
435
+ default_field_extras: dict[str, Any] | None = None,
449
436
  target_datetime_class: DatetimeClassType = DatetimeClassType.Datetime,
450
437
  keyword_only: bool = False,
451
438
  no_alias: bool = False,
@@ -524,12 +511,12 @@ class JsonSchemaParser(Parser):
524
511
  no_alias=no_alias,
525
512
  )
526
513
 
527
- self.remote_object_cache: DefaultPutDict[str, Dict[str, Any]] = DefaultPutDict()
528
- self.raw_obj: Dict[Any, Any] = {}
529
- self._root_id: Optional[str] = None
530
- self._root_id_base_path: Optional[str] = None
531
- self.reserved_refs: DefaultDict[Tuple[str, ...], Set[str]] = defaultdict(set)
532
- self.field_keys: Set[str] = {
514
+ self.remote_object_cache: DefaultPutDict[str, dict[str, Any]] = DefaultPutDict()
515
+ self.raw_obj: dict[Any, Any] = {}
516
+ self._root_id: Optional[str] = None # noqa: UP045
517
+ self._root_id_base_path: Optional[str] = None # noqa: UP045
518
+ self.reserved_refs: defaultdict[tuple[str, ...], set[str]] = defaultdict(set)
519
+ self.field_keys: set[str] = {
533
520
  *DEFAULT_FIELD_KEYS,
534
521
  *self.field_extra_keys,
535
522
  *self.field_extra_keys_without_x_prefix,
@@ -543,19 +530,15 @@ class JsonSchemaParser(Parser):
543
530
  else:
544
531
  self.get_field_extra_key = lambda key: key
545
532
 
546
- def get_field_extras(self, obj: JsonSchemaObject) -> Dict[str, Any]:
533
+ def get_field_extras(self, obj: JsonSchemaObject) -> dict[str, Any]:
547
534
  if self.field_include_all_keys:
548
535
  extras = {
549
- self.get_field_extra_key(
550
- k.lstrip('x-') if k in self.field_extra_keys_without_x_prefix else k
551
- ): v
536
+ self.get_field_extra_key(k.lstrip("x-") if k in self.field_extra_keys_without_x_prefix else k): v
552
537
  for k, v in obj.extras.items()
553
538
  }
554
539
  else:
555
540
  extras = {
556
- self.get_field_extra_key(
557
- k.lstrip('x-') if k in self.field_extra_keys_without_x_prefix else k
558
- ): v
541
+ self.get_field_extra_key(k.lstrip("x-") if k in self.field_extra_keys_without_x_prefix else k): v
559
542
  for k, v in obj.extras.items()
560
543
  if k in self.field_keys
561
544
  }
@@ -564,15 +547,15 @@ class JsonSchemaParser(Parser):
564
547
  return extras
565
548
 
566
549
  @cached_property
567
- def schema_paths(self) -> List[Tuple[str, List[str]]]:
568
- return [(s, s.lstrip('#/').split('/')) for s in self.SCHEMA_PATHS]
550
+ def schema_paths(self) -> list[tuple[str, list[str]]]:
551
+ return [(s, s.lstrip("#/").split("/")) for s in self.SCHEMA_PATHS]
569
552
 
570
553
  @property
571
- def root_id(self) -> Optional[str]:
554
+ def root_id(self) -> str | None:
572
555
  return self.model_resolver.root_id
573
556
 
574
557
  @root_id.setter
575
- def root_id(self, value: Optional[str]) -> None:
558
+ def root_id(self, value: str | None) -> None:
576
559
  self.model_resolver.set_root_id(value)
577
560
 
578
561
  def should_parse_enum_as_literal(self, obj: JsonSchemaObject) -> bool:
@@ -582,26 +565,18 @@ class JsonSchemaParser(Parser):
582
565
 
583
566
  def is_constraints_field(self, obj: JsonSchemaObject) -> bool:
584
567
  return obj.is_array or (
585
- self.field_constraints
586
- and not (
587
- obj.ref
588
- or obj.anyOf
589
- or obj.oneOf
590
- or obj.allOf
591
- or obj.is_object
592
- or obj.enum
593
- )
568
+ self.field_constraints and not (obj.ref or obj.anyOf or obj.oneOf or obj.allOf or obj.is_object or obj.enum)
594
569
  )
595
570
 
596
- def get_object_field(
571
+ def get_object_field( # noqa: PLR0913
597
572
  self,
598
573
  *,
599
- field_name: Optional[str],
574
+ field_name: str | None,
600
575
  field: JsonSchemaObject,
601
576
  required: bool,
602
577
  field_type: DataType,
603
- alias: Optional[str],
604
- original_field_name: Optional[str],
578
+ alias: str | None,
579
+ original_field_name: str | None,
605
580
  ) -> DataModelFieldBase:
606
581
  return self.data_model_field_type(
607
582
  name=field_name,
@@ -610,9 +585,7 @@ class JsonSchemaParser(Parser):
610
585
  required=required,
611
586
  alias=alias,
612
587
  constraints=field.dict() if self.is_constraints_field(field) else None,
613
- nullable=field.nullable
614
- if self.strict_nullable and (field.has_default or required)
615
- else None,
588
+ nullable=field.nullable if self.strict_nullable and (field.has_default or required) else None,
616
589
  strip_default_none=self.strip_default_none,
617
590
  extras=self.get_field_extras(field),
618
591
  use_annotated=self.use_annotated,
@@ -625,10 +598,8 @@ class JsonSchemaParser(Parser):
625
598
 
626
599
  def get_data_type(self, obj: JsonSchemaObject) -> DataType:
627
600
  if obj.type is None:
628
- if 'const' in obj.extras:
629
- return self.data_type_manager.get_data_type_from_value(
630
- obj.extras['const']
631
- )
601
+ if "const" in obj.extras:
602
+ return self.data_type_manager.get_data_type_from_value(obj.extras["const"])
632
603
  return self.data_type_manager.get_data_type(
633
604
  Types.any,
634
605
  )
@@ -641,14 +612,10 @@ class JsonSchemaParser(Parser):
641
612
 
642
613
  if isinstance(obj.type, list):
643
614
  return self.data_type(
644
- data_types=[
645
- _get_data_type(t, obj.format or 'default')
646
- for t in obj.type
647
- if t != 'null'
648
- ],
649
- is_optional='null' in obj.type,
615
+ data_types=[_get_data_type(t, obj.format or "default") for t in obj.type if t != "null"],
616
+ is_optional="null" in obj.type,
650
617
  )
651
- return _get_data_type(obj.type, obj.format or 'default')
618
+ return _get_data_type(obj.type, obj.format or "default")
652
619
 
653
620
  def get_ref_data_type(self, ref: str) -> DataType:
654
621
  reference = self.model_resolver.add_ref(ref)
@@ -656,25 +623,21 @@ class JsonSchemaParser(Parser):
656
623
 
657
624
  def set_additional_properties(self, name: str, obj: JsonSchemaObject) -> None:
658
625
  if isinstance(obj.additionalProperties, bool):
659
- self.extra_template_data[name]['additionalProperties'] = (
660
- obj.additionalProperties
661
- )
626
+ self.extra_template_data[name]["additionalProperties"] = obj.additionalProperties
662
627
 
663
628
  def set_title(self, name: str, obj: JsonSchemaObject) -> None:
664
629
  if obj.title:
665
- self.extra_template_data[name]['title'] = obj.title
630
+ self.extra_template_data[name]["title"] = obj.title
666
631
 
667
- def _deep_merge(
668
- self, dict1: Dict[Any, Any], dict2: Dict[Any, Any]
669
- ) -> Dict[Any, Any]:
632
+ def _deep_merge(self, dict1: dict[Any, Any], dict2: dict[Any, Any]) -> dict[Any, Any]:
670
633
  result = dict1.copy()
671
634
  for key, value in dict2.items():
672
635
  if key in result:
673
636
  if isinstance(result[key], dict) and isinstance(value, dict):
674
637
  result[key] = self._deep_merge(result[key], value)
675
638
  continue
676
- elif isinstance(result[key], list) and isinstance(value, list):
677
- result[key] = result[key] + value
639
+ if isinstance(result[key], list) and isinstance(value, list):
640
+ result[key] += value
678
641
  continue
679
642
  result[key] = value
680
643
  return result
@@ -683,34 +646,17 @@ class JsonSchemaParser(Parser):
683
646
  self,
684
647
  name: str,
685
648
  obj: JsonSchemaObject,
686
- path: List[str],
649
+ path: list[str],
687
650
  target_attribute_name: str,
688
- ) -> List[DataType]:
689
- base_object = obj.dict(
690
- exclude={target_attribute_name}, exclude_unset=True, by_alias=True
691
- )
692
- combined_schemas: List[JsonSchemaObject] = []
651
+ ) -> list[DataType]:
652
+ base_object = obj.dict(exclude={target_attribute_name}, exclude_unset=True, by_alias=True)
653
+ combined_schemas: list[JsonSchemaObject] = []
693
654
  refs = []
694
- for index, target_attribute in enumerate(
695
- getattr(obj, target_attribute_name, [])
696
- ):
655
+ for index, target_attribute in enumerate(getattr(obj, target_attribute_name, [])):
697
656
  if target_attribute.ref:
698
657
  combined_schemas.append(target_attribute)
699
658
  refs.append(index)
700
659
  # TODO: support partial ref
701
- # {
702
- # "type": "integer",
703
- # "oneOf": [
704
- # { "minimum": 5 },
705
- # { "$ref": "#/definitions/positive" }
706
- # ],
707
- # "definitions": {
708
- # "positive": {
709
- # "minimum": 0,
710
- # "exclusiveMinimum": true
711
- # }
712
- # }
713
- # }
714
660
  else:
715
661
  combined_schemas.append(
716
662
  self.SCHEMA_OBJECT_TYPE.parse_obj(
@@ -728,7 +674,7 @@ class JsonSchemaParser(Parser):
728
674
  obj,
729
675
  singular_name=False,
730
676
  )
731
- common_path_keyword = f'{target_attribute_name}Common'
677
+ common_path_keyword = f"{target_attribute_name}Common"
732
678
  return [
733
679
  self._parse_object_common_part(
734
680
  name,
@@ -744,35 +690,27 @@ class JsonSchemaParser(Parser):
744
690
  for i, d in enumerate(parsed_schemas)
745
691
  ]
746
692
 
747
- def parse_any_of(
748
- self, name: str, obj: JsonSchemaObject, path: List[str]
749
- ) -> List[DataType]:
750
- return self.parse_combined_schema(name, obj, path, 'anyOf')
693
+ def parse_any_of(self, name: str, obj: JsonSchemaObject, path: list[str]) -> list[DataType]:
694
+ return self.parse_combined_schema(name, obj, path, "anyOf")
751
695
 
752
- def parse_one_of(
753
- self, name: str, obj: JsonSchemaObject, path: List[str]
754
- ) -> List[DataType]:
755
- return self.parse_combined_schema(name, obj, path, 'oneOf')
696
+ def parse_one_of(self, name: str, obj: JsonSchemaObject, path: list[str]) -> list[DataType]:
697
+ return self.parse_combined_schema(name, obj, path, "oneOf")
756
698
 
757
- def _parse_object_common_part(
699
+ def _parse_object_common_part( # noqa: PLR0913, PLR0917
758
700
  self,
759
701
  name: str,
760
702
  obj: JsonSchemaObject,
761
- path: List[str],
762
- ignore_duplicate_model: bool,
763
- fields: List[DataModelFieldBase],
764
- base_classes: List[Reference],
765
- required: List[str],
703
+ path: list[str],
704
+ ignore_duplicate_model: bool, # noqa: FBT001
705
+ fields: list[DataModelFieldBase],
706
+ base_classes: list[Reference],
707
+ required: list[str],
766
708
  ) -> DataType:
767
709
  if obj.properties:
768
- fields.extend(
769
- self.parse_object_fields(obj, path, get_module_name(name, None))
770
- )
710
+ fields.extend(self.parse_object_fields(obj, path, get_module_name(name, None)))
771
711
  # ignore an undetected object
772
712
  if ignore_duplicate_model and not fields and len(base_classes) == 1:
773
- with self.model_resolver.current_base_path_context(
774
- self.model_resolver._base_path
775
- ):
713
+ with self.model_resolver.current_base_path_context(self.model_resolver._base_path): # noqa: SLF001
776
714
  self.model_resolver.delete(path)
777
715
  return self.data_type(reference=base_classes[0])
778
716
  if required:
@@ -789,16 +727,13 @@ class JsonSchemaParser(Parser):
789
727
  if required_ in field_name_to_field:
790
728
  field = field_name_to_field[required_]
791
729
  if self.force_optional_for_required_fields or (
792
- self.apply_default_values_for_required_fields
793
- and field.has_default
730
+ self.apply_default_values_for_required_fields and field.has_default
794
731
  ):
795
732
  continue
796
733
  field.required = True
797
734
  else:
798
735
  fields.append(
799
- self.data_model_field_type(
800
- required=True, original_name=required_, data_type=DataType()
801
- )
736
+ self.data_model_field_type(required=True, original_name=required_, data_type=DataType())
802
737
  )
803
738
  if self.use_title_as_name and obj.title: # pragma: no cover
804
739
  name = obj.title
@@ -819,15 +754,15 @@ class JsonSchemaParser(Parser):
819
754
 
820
755
  return self.data_type(reference=reference)
821
756
 
822
- def _parse_all_of_item(
757
+ def _parse_all_of_item( # noqa: PLR0913, PLR0917
823
758
  self,
824
759
  name: str,
825
760
  obj: JsonSchemaObject,
826
- path: List[str],
827
- fields: List[DataModelFieldBase],
828
- base_classes: List[Reference],
829
- required: List[str],
830
- union_models: List[Reference],
761
+ path: list[str],
762
+ fields: list[DataModelFieldBase],
763
+ base_classes: list[Reference],
764
+ required: list[str],
765
+ union_models: list[Reference],
831
766
  ) -> None:
832
767
  for all_of_item in obj.allOf:
833
768
  if all_of_item.ref: # $ref
@@ -842,9 +777,8 @@ class JsonSchemaParser(Parser):
842
777
 
843
778
  if object_fields:
844
779
  fields.extend(object_fields)
845
- else:
846
- if all_of_item.required:
847
- required.extend(all_of_item.required)
780
+ elif all_of_item.required:
781
+ required.extend(all_of_item.required)
848
782
  self._parse_all_of_item(
849
783
  name,
850
784
  all_of_item,
@@ -856,40 +790,31 @@ class JsonSchemaParser(Parser):
856
790
  )
857
791
  if all_of_item.anyOf:
858
792
  self.model_resolver.add(path, name, class_name=True, loaded=True)
859
- union_models.extend(
860
- d.reference
861
- for d in self.parse_any_of(name, all_of_item, path)
862
- if d.reference
863
- )
793
+ union_models.extend(d.reference for d in self.parse_any_of(name, all_of_item, path) if d.reference)
864
794
  if all_of_item.oneOf:
865
795
  self.model_resolver.add(path, name, class_name=True, loaded=True)
866
- union_models.extend(
867
- d.reference
868
- for d in self.parse_one_of(name, all_of_item, path)
869
- if d.reference
870
- )
796
+ union_models.extend(d.reference for d in self.parse_one_of(name, all_of_item, path) if d.reference)
871
797
 
872
798
  def parse_all_of(
873
799
  self,
874
800
  name: str,
875
801
  obj: JsonSchemaObject,
876
- path: List[str],
877
- ignore_duplicate_model: bool = False,
802
+ path: list[str],
803
+ ignore_duplicate_model: bool = False, # noqa: FBT001, FBT002
878
804
  ) -> DataType:
879
805
  if len(obj.allOf) == 1 and not obj.properties:
880
806
  single_obj = obj.allOf[0]
881
- if single_obj.ref and single_obj.ref_type == JSONReference.LOCAL:
882
- if get_model_by_path(self.raw_obj, single_obj.ref[2:].split('/')).get(
883
- 'enum'
884
- ):
885
- return self.get_ref_data_type(single_obj.ref)
886
- fields: List[DataModelFieldBase] = []
887
- base_classes: List[Reference] = []
888
- required: List[str] = []
889
- union_models: List[Reference] = []
890
- self._parse_all_of_item(
891
- name, obj, path, fields, base_classes, required, union_models
892
- )
807
+ if (
808
+ single_obj.ref
809
+ and single_obj.ref_type == JSONReference.LOCAL
810
+ and get_model_by_path(self.raw_obj, single_obj.ref[2:].split("/")).get("enum")
811
+ ):
812
+ return self.get_ref_data_type(single_obj.ref)
813
+ fields: list[DataModelFieldBase] = []
814
+ base_classes: list[Reference] = []
815
+ required: list[str] = []
816
+ union_models: list[Reference] = []
817
+ self._parse_all_of_item(name, obj, path, fields, base_classes, required, union_models)
893
818
  if not union_models:
894
819
  return self._parse_object_common_part(
895
820
  name, obj, path, ignore_duplicate_model, fields, base_classes, required
@@ -898,21 +823,22 @@ class JsonSchemaParser(Parser):
898
823
  all_of_data_type = self._parse_object_common_part(
899
824
  name,
900
825
  obj,
901
- get_special_path('allOf', path),
826
+ get_special_path("allOf", path),
902
827
  ignore_duplicate_model,
903
828
  fields,
904
829
  base_classes,
905
830
  required,
906
831
  )
832
+ assert all_of_data_type.reference is not None
907
833
  data_type = self.data_type(
908
834
  data_types=[
909
835
  self._parse_object_common_part(
910
836
  name,
911
837
  obj,
912
- get_special_path(f'union_model-{index}', path),
838
+ get_special_path(f"union_model-{index}", path),
913
839
  ignore_duplicate_model,
914
840
  [],
915
- [union_model, all_of_data_type.reference], # type: ignore
841
+ [union_model, all_of_data_type.reference],
916
842
  [],
917
843
  )
918
844
  for index, union_model in enumerate(union_models)
@@ -940,20 +866,21 @@ class JsonSchemaParser(Parser):
940
866
  return self.data_type(reference=reference)
941
867
 
942
868
  def parse_object_fields(
943
- self, obj: JsonSchemaObject, path: List[str], module_name: Optional[str] = None
944
- ) -> List[DataModelFieldBase]:
945
- properties: Dict[str, Union[JsonSchemaObject, bool]] = (
946
- {} if obj.properties is None else obj.properties
947
- )
948
- requires: Set[str] = {*()} if obj.required is None else {*obj.required}
949
- fields: List[DataModelFieldBase] = []
950
-
951
- exclude_field_names: Set[str] = set()
869
+ self,
870
+ obj: JsonSchemaObject,
871
+ path: list[str],
872
+ module_name: Optional[str] = None, # noqa: UP045
873
+ ) -> list[DataModelFieldBase]:
874
+ properties: dict[str, JsonSchemaObject | bool] = {} if obj.properties is None else obj.properties
875
+ requires: set[str] = {*()} if obj.required is None else {*obj.required}
876
+ fields: list[DataModelFieldBase] = []
877
+
878
+ exclude_field_names: set[str] = set()
952
879
  for original_field_name, field in properties.items():
953
880
  field_name, alias = self.model_resolver.get_valid_field_name_and_alias(
954
881
  original_field_name, exclude_field_names
955
882
  )
956
- modular_name = f'{module_name}.{field_name}' if module_name else field_name
883
+ modular_name = f"{module_name}.{field_name}" if module_name else field_name
957
884
 
958
885
  exclude_field_names.add(field_name)
959
886
 
@@ -964,9 +891,7 @@ class JsonSchemaParser(Parser):
964
891
  data_type=self.data_type_manager.get_data_type(
965
892
  Types.any,
966
893
  ),
967
- required=False
968
- if self.force_optional_for_required_fields
969
- else original_field_name in requires,
894
+ required=False if self.force_optional_for_required_fields else original_field_name in requires,
970
895
  alias=alias,
971
896
  strip_default_none=self.strip_default_none,
972
897
  use_annotated=self.use_annotated,
@@ -1000,15 +925,16 @@ class JsonSchemaParser(Parser):
1000
925
  self,
1001
926
  name: str,
1002
927
  obj: JsonSchemaObject,
1003
- path: List[str],
1004
- singular_name: bool = False,
1005
- unique: bool = True,
928
+ path: list[str],
929
+ singular_name: bool = False, # noqa: FBT001, FBT002
930
+ unique: bool = True, # noqa: FBT001, FBT002
1006
931
  ) -> DataType:
1007
932
  if not unique: # pragma: no cover
1008
933
  warn(
1009
- f'{self.__class__.__name__}.parse_object() ignore `unique` argument.'
1010
- f'An object name must be unique.'
1011
- f'This argument will be removed in a future version'
934
+ f"{self.__class__.__name__}.parse_object() ignore `unique` argument."
935
+ f"An object name must be unique."
936
+ f"This argument will be removed in a future version",
937
+ stacklevel=2,
1012
938
  )
1013
939
  if self.use_title_as_name and obj.title:
1014
940
  name = obj.title
@@ -1037,7 +963,7 @@ class JsonSchemaParser(Parser):
1037
963
  # TODO: Improve naming for nested ClassName
1038
964
  name,
1039
965
  obj.additionalProperties,
1040
- [*path, 'additionalProperties'],
966
+ [*path, "additionalProperties"],
1041
967
  )
1042
968
  ],
1043
969
  is_dict=True,
@@ -1065,8 +991,8 @@ class JsonSchemaParser(Parser):
1065
991
  def parse_pattern_properties(
1066
992
  self,
1067
993
  name: str,
1068
- pattern_properties: Dict[str, JsonSchemaObject],
1069
- path: List[str],
994
+ pattern_properties: dict[str, JsonSchemaObject],
995
+ path: list[str],
1070
996
  ) -> DataType:
1071
997
  return self.data_type(
1072
998
  data_types=[
@@ -1075,7 +1001,7 @@ class JsonSchemaParser(Parser):
1075
1001
  self.parse_item(
1076
1002
  name,
1077
1003
  kv[1],
1078
- get_special_path(f'patternProperties/{i}', path),
1004
+ get_special_path(f"patternProperties/{i}", path),
1079
1005
  )
1080
1006
  ],
1081
1007
  is_dict=True,
@@ -1088,24 +1014,19 @@ class JsonSchemaParser(Parser):
1088
1014
  ],
1089
1015
  )
1090
1016
 
1091
- def parse_item(
1017
+ def parse_item( # noqa: PLR0911, PLR0912
1092
1018
  self,
1093
1019
  name: str,
1094
1020
  item: JsonSchemaObject,
1095
- path: List[str],
1096
- singular_name: bool = False,
1097
- parent: Optional[JsonSchemaObject] = None,
1021
+ path: list[str],
1022
+ singular_name: bool = False, # noqa: FBT001, FBT002
1023
+ parent: JsonSchemaObject | None = None,
1098
1024
  ) -> DataType:
1099
1025
  if self.use_title_as_name and item.title:
1100
1026
  name = item.title
1101
1027
  singular_name = False
1102
- if (
1103
- parent
1104
- and not item.enum
1105
- and item.has_constraint
1106
- and (parent.has_constraint or self.field_constraints)
1107
- ):
1108
- root_type_path = get_special_path('array', path)
1028
+ if parent and not item.enum and item.has_constraint and (parent.has_constraint or self.field_constraints):
1029
+ root_type_path = get_special_path("array", path)
1109
1030
  return self.parse_root_type(
1110
1031
  self.model_resolver.add(
1111
1032
  root_type_path,
@@ -1116,83 +1037,56 @@ class JsonSchemaParser(Parser):
1116
1037
  item,
1117
1038
  root_type_path,
1118
1039
  )
1119
- elif item.ref:
1040
+ if item.ref:
1120
1041
  return self.get_ref_data_type(item.ref)
1121
- elif item.custom_type_path:
1122
- return self.data_type_manager.get_data_type_from_full_path(
1123
- item.custom_type_path, is_custom_type=True
1124
- )
1125
- elif item.is_array:
1126
- return self.parse_array_fields(
1127
- name, item, get_special_path('array', path)
1128
- ).data_type
1129
- elif (
1130
- item.discriminator
1131
- and parent
1132
- and parent.is_array
1133
- and (item.oneOf or item.anyOf)
1134
- ):
1042
+ if item.custom_type_path:
1043
+ return self.data_type_manager.get_data_type_from_full_path(item.custom_type_path, is_custom_type=True)
1044
+ if item.is_array:
1045
+ return self.parse_array_fields(name, item, get_special_path("array", path)).data_type
1046
+ if item.discriminator and parent and parent.is_array and (item.oneOf or item.anyOf):
1135
1047
  return self.parse_root_type(name, item, path)
1136
- elif item.anyOf:
1137
- return self.data_type(
1138
- data_types=self.parse_any_of(
1139
- name, item, get_special_path('anyOf', path)
1140
- )
1141
- )
1142
- elif item.oneOf:
1143
- return self.data_type(
1144
- data_types=self.parse_one_of(
1145
- name, item, get_special_path('oneOf', path)
1146
- )
1147
- )
1148
- elif item.allOf:
1149
- all_of_path = get_special_path('allOf', path)
1048
+ if item.anyOf:
1049
+ return self.data_type(data_types=self.parse_any_of(name, item, get_special_path("anyOf", path)))
1050
+ if item.oneOf:
1051
+ return self.data_type(data_types=self.parse_one_of(name, item, get_special_path("oneOf", path)))
1052
+ if item.allOf:
1053
+ all_of_path = get_special_path("allOf", path)
1150
1054
  all_of_path = [self.model_resolver.resolve_ref(all_of_path)]
1151
1055
  return self.parse_all_of(
1152
- self.model_resolver.add(
1153
- all_of_path, name, singular_name=singular_name, class_name=True
1154
- ).name,
1056
+ self.model_resolver.add(all_of_path, name, singular_name=singular_name, class_name=True).name,
1155
1057
  item,
1156
1058
  all_of_path,
1157
1059
  ignore_duplicate_model=True,
1158
1060
  )
1159
- elif item.is_object or item.patternProperties:
1160
- object_path = get_special_path('object', path)
1061
+ if item.is_object or item.patternProperties:
1062
+ object_path = get_special_path("object", path)
1161
1063
  if item.properties:
1162
- return self.parse_object(
1163
- name, item, object_path, singular_name=singular_name
1164
- )
1165
- elif item.patternProperties:
1064
+ return self.parse_object(name, item, object_path, singular_name=singular_name)
1065
+ if item.patternProperties:
1166
1066
  # support only single key dict.
1167
- return self.parse_pattern_properties(
1168
- name, item.patternProperties, object_path
1169
- )
1170
- elif isinstance(item.additionalProperties, JsonSchemaObject):
1067
+ return self.parse_pattern_properties(name, item.patternProperties, object_path)
1068
+ if isinstance(item.additionalProperties, JsonSchemaObject):
1171
1069
  return self.data_type(
1172
- data_types=[
1173
- self.parse_item(name, item.additionalProperties, object_path)
1174
- ],
1070
+ data_types=[self.parse_item(name, item.additionalProperties, object_path)],
1175
1071
  is_dict=True,
1176
1072
  )
1177
1073
  return self.data_type_manager.get_data_type(
1178
1074
  Types.object,
1179
1075
  )
1180
- elif item.enum:
1076
+ if item.enum:
1181
1077
  if self.should_parse_enum_as_literal(item):
1182
1078
  return self.parse_enum_as_literal(item)
1183
- return self.parse_enum(
1184
- name, item, get_special_path('enum', path), singular_name=singular_name
1185
- )
1079
+ return self.parse_enum(name, item, get_special_path("enum", path), singular_name=singular_name)
1186
1080
  return self.get_data_type(item)
1187
1081
 
1188
1082
  def parse_list_item(
1189
1083
  self,
1190
1084
  name: str,
1191
- target_items: List[JsonSchemaObject],
1192
- path: List[str],
1085
+ target_items: list[JsonSchemaObject],
1086
+ path: list[str],
1193
1087
  parent: JsonSchemaObject,
1194
- singular_name: bool = True,
1195
- ) -> List[DataType]:
1088
+ singular_name: bool = True, # noqa: FBT001, FBT002
1089
+ ) -> list[DataType]:
1196
1090
  return [
1197
1091
  self.parse_item(
1198
1092
  name,
@@ -1208,29 +1102,27 @@ class JsonSchemaParser(Parser):
1208
1102
  self,
1209
1103
  name: str,
1210
1104
  obj: JsonSchemaObject,
1211
- path: List[str],
1212
- singular_name: bool = True,
1105
+ path: list[str],
1106
+ singular_name: bool = True, # noqa: FBT001, FBT002
1213
1107
  ) -> DataModelFieldBase:
1214
1108
  if self.force_optional_for_required_fields:
1215
1109
  required: bool = False
1216
- nullable: Optional[bool] = None
1110
+ nullable: Optional[bool] = None # noqa: UP045
1217
1111
  else:
1218
- required = not (
1219
- obj.has_default and self.apply_default_values_for_required_fields
1220
- )
1112
+ required = not (obj.has_default and self.apply_default_values_for_required_fields)
1221
1113
  if self.strict_nullable:
1222
1114
  nullable = obj.nullable if obj.has_default or required else True
1223
1115
  else:
1224
1116
  required = not obj.nullable and required
1225
1117
  nullable = None
1226
1118
  if isinstance(obj.items, JsonSchemaObject):
1227
- items: List[JsonSchemaObject] = [obj.items]
1119
+ items: list[JsonSchemaObject] = [obj.items]
1228
1120
  elif isinstance(obj.items, list):
1229
1121
  items = obj.items
1230
1122
  else:
1231
1123
  items = []
1232
1124
 
1233
- data_types: List[DataType] = [
1125
+ data_types: list[DataType] = [
1234
1126
  self.data_type(
1235
1127
  data_types=self.parse_list_item(
1236
1128
  name,
@@ -1244,17 +1136,11 @@ class JsonSchemaParser(Parser):
1244
1136
  ]
1245
1137
  # TODO: decide special path word for a combined data model.
1246
1138
  if obj.allOf:
1247
- data_types.append(
1248
- self.parse_all_of(name, obj, get_special_path('allOf', path))
1249
- )
1139
+ data_types.append(self.parse_all_of(name, obj, get_special_path("allOf", path)))
1250
1140
  elif obj.is_object:
1251
- data_types.append(
1252
- self.parse_object(name, obj, get_special_path('object', path))
1253
- )
1141
+ data_types.append(self.parse_object(name, obj, get_special_path("object", path)))
1254
1142
  if obj.enum:
1255
- data_types.append(
1256
- self.parse_enum(name, obj, get_special_path('enum', path))
1257
- )
1143
+ data_types.append(self.parse_enum(name, obj, get_special_path("enum", path)))
1258
1144
  return self.data_model_field_type(
1259
1145
  data_type=self.data_type(data_types=data_types),
1260
1146
  default=obj.default,
@@ -1273,24 +1159,20 @@ class JsonSchemaParser(Parser):
1273
1159
  self,
1274
1160
  name: str,
1275
1161
  obj: JsonSchemaObject,
1276
- path: List[str],
1277
- original_name: Optional[str] = None,
1162
+ path: list[str],
1163
+ original_name: str | None = None,
1278
1164
  ) -> DataType:
1279
1165
  if self.use_title_as_name and obj.title:
1280
1166
  name = obj.title
1281
1167
  reference = self.model_resolver.add(path, name, loaded=True, class_name=True)
1282
1168
  field = self.parse_array_fields(original_name or name, obj, [*path, name])
1283
1169
 
1284
- if reference in [
1285
- d.reference for d in field.data_type.all_data_types if d.reference
1286
- ]:
1170
+ if reference in [d.reference for d in field.data_type.all_data_types if d.reference]:
1287
1171
  # self-reference
1288
1172
  field = self.data_model_field_type(
1289
1173
  data_type=self.data_type(
1290
1174
  data_types=[
1291
- self.data_type(
1292
- data_types=field.data_type.data_types[1:], is_list=True
1293
- ),
1175
+ self.data_type(data_types=field.data_type.data_types[1:], is_list=True),
1294
1176
  *field.data_type.data_types[1:],
1295
1177
  ]
1296
1178
  ),
@@ -1319,13 +1201,13 @@ class JsonSchemaParser(Parser):
1319
1201
  self.results.append(data_model_root)
1320
1202
  return self.data_type(reference=reference)
1321
1203
 
1322
- def parse_root_type(
1204
+ def parse_root_type( # noqa: PLR0912
1323
1205
  self,
1324
1206
  name: str,
1325
1207
  obj: JsonSchemaObject,
1326
- path: List[str],
1208
+ path: list[str],
1327
1209
  ) -> DataType:
1328
- reference: Optional[Reference] = None
1210
+ reference: Reference | None = None
1329
1211
  if obj.ref:
1330
1212
  data_type: DataType = self.get_ref_data_type(obj.ref)
1331
1213
  elif obj.custom_type_path:
@@ -1334,20 +1216,14 @@ class JsonSchemaParser(Parser):
1334
1216
  ) # pragma: no cover
1335
1217
  elif obj.is_array:
1336
1218
  data_type = self.parse_array_fields(
1337
- name, obj, get_special_path('array', path)
1219
+ name, obj, get_special_path("array", path)
1338
1220
  ).data_type # pragma: no cover
1339
1221
  elif obj.anyOf or obj.oneOf:
1340
- reference = self.model_resolver.add(
1341
- path, name, loaded=True, class_name=True
1342
- )
1222
+ reference = self.model_resolver.add(path, name, loaded=True, class_name=True)
1343
1223
  if obj.anyOf:
1344
- data_types: List[DataType] = self.parse_any_of(
1345
- name, obj, get_special_path('anyOf', path)
1346
- )
1224
+ data_types: list[DataType] = self.parse_any_of(name, obj, get_special_path("anyOf", path))
1347
1225
  else:
1348
- data_types = self.parse_one_of(
1349
- name, obj, get_special_path('oneOf', path)
1350
- )
1226
+ data_types = self.parse_one_of(name, obj, get_special_path("oneOf", path))
1351
1227
 
1352
1228
  if len(data_types) > 1: # pragma: no cover
1353
1229
  data_type = self.data_type(data_types=data_types)
@@ -1371,15 +1247,11 @@ class JsonSchemaParser(Parser):
1371
1247
  if self.force_optional_for_required_fields:
1372
1248
  required: bool = False
1373
1249
  else:
1374
- required = not obj.nullable and not (
1375
- obj.has_default and self.apply_default_values_for_required_fields
1376
- )
1250
+ required = not obj.nullable and not (obj.has_default and self.apply_default_values_for_required_fields)
1377
1251
  if self.use_title_as_name and obj.title:
1378
1252
  name = obj.title
1379
1253
  if not reference:
1380
- reference = self.model_resolver.add(
1381
- path, name, loaded=True, class_name=True
1382
- )
1254
+ reference = self.model_resolver.add(path, name, loaded=True, class_name=True)
1383
1255
  self.set_title(name, obj)
1384
1256
  self.set_additional_properties(name, obj)
1385
1257
  data_model_root_type = self.data_model_root_type(
@@ -1415,19 +1287,20 @@ class JsonSchemaParser(Parser):
1415
1287
  self,
1416
1288
  name: str,
1417
1289
  obj: JsonSchemaObject,
1418
- path: List[str],
1419
- singular_name: bool = False,
1420
- unique: bool = True,
1290
+ path: list[str],
1291
+ singular_name: bool = False, # noqa: FBT001, FBT002
1292
+ unique: bool = True, # noqa: FBT001, FBT002
1421
1293
  ) -> DataType:
1422
1294
  if not unique: # pragma: no cover
1423
1295
  warn(
1424
- f'{self.__class__.__name__}.parse_enum() ignore `unique` argument.'
1425
- f'An object name must be unique.'
1426
- f'This argument will be removed in a future version'
1296
+ f"{self.__class__.__name__}.parse_enum() ignore `unique` argument."
1297
+ f"An object name must be unique."
1298
+ f"This argument will be removed in a future version",
1299
+ stacklevel=2,
1427
1300
  )
1428
- enum_fields: List[DataModelFieldBase] = []
1301
+ enum_fields: list[DataModelFieldBase] = []
1429
1302
 
1430
- if None in obj.enum and obj.type == 'string':
1303
+ if None in obj.enum and obj.type == "string":
1431
1304
  # Nullable is valid in only OpenAPI
1432
1305
  nullable: bool = True
1433
1306
  enum_times = [e for e in obj.enum if e is not None]
@@ -1435,30 +1308,19 @@ class JsonSchemaParser(Parser):
1435
1308
  enum_times = obj.enum
1436
1309
  nullable = False
1437
1310
 
1438
- exclude_field_names: Set[str] = set()
1311
+ exclude_field_names: set[str] = set()
1439
1312
 
1440
1313
  for i, enum_part in enumerate(enum_times):
1441
- if obj.type == 'string' or isinstance(enum_part, str):
1442
- default = (
1443
- f"'{enum_part.translate(escape_characters)}'"
1444
- if isinstance(enum_part, str)
1445
- else enum_part
1446
- )
1447
- if obj.x_enum_varnames:
1448
- field_name = obj.x_enum_varnames[i]
1449
- else:
1450
- field_name = str(enum_part)
1314
+ if obj.type == "string" or isinstance(enum_part, str):
1315
+ default = f"'{enum_part.translate(escape_characters)}'" if isinstance(enum_part, str) else enum_part
1316
+ field_name = obj.x_enum_varnames[i] if obj.x_enum_varnames else str(enum_part)
1451
1317
  else:
1452
1318
  default = enum_part
1453
1319
  if obj.x_enum_varnames:
1454
1320
  field_name = obj.x_enum_varnames[i]
1455
1321
  else:
1456
- prefix = (
1457
- obj.type
1458
- if isinstance(obj.type, str)
1459
- else type(enum_part).__name__
1460
- )
1461
- field_name = f'{prefix}_{enum_part}'
1322
+ prefix = obj.type if isinstance(obj.type, str) else type(enum_part).__name__
1323
+ field_name = f"{prefix}_{enum_part}"
1462
1324
  field_name = self.model_resolver.get_valid_field_name(
1463
1325
  field_name, excludes=exclude_field_names, model_type=ModelType.ENUM
1464
1326
  )
@@ -1485,9 +1347,7 @@ class JsonSchemaParser(Parser):
1485
1347
  path=self.current_source_path,
1486
1348
  description=obj.description if self.use_schema_description else None,
1487
1349
  custom_template_dir=self.custom_template_dir,
1488
- type_=_get_type(obj.type, obj.format)
1489
- if self.use_subclass_enum and isinstance(obj.type, str)
1490
- else None,
1350
+ type_=_get_type(obj.type, obj.format) if self.use_subclass_enum and isinstance(obj.type, str) else None,
1491
1351
  default=obj.default if obj.has_default else UNDEFINED,
1492
1352
  )
1493
1353
  self.results.append(enum)
@@ -1500,7 +1360,7 @@ class JsonSchemaParser(Parser):
1500
1360
  name,
1501
1361
  class_name=True,
1502
1362
  singular_name=singular_name,
1503
- singular_name_suffix='Enum',
1363
+ singular_name_suffix="Enum",
1504
1364
  loaded=True,
1505
1365
  )
1506
1366
 
@@ -1508,11 +1368,11 @@ class JsonSchemaParser(Parser):
1508
1368
  return create_enum(reference)
1509
1369
 
1510
1370
  enum_reference = self.model_resolver.add(
1511
- [*path, 'Enum'],
1512
- f'{reference.name}Enum',
1371
+ [*path, "Enum"],
1372
+ f"{reference.name}Enum",
1513
1373
  class_name=True,
1514
1374
  singular_name=singular_name,
1515
- singular_name_suffix='Enum',
1375
+ singular_name_suffix="Enum",
1516
1376
  loaded=True,
1517
1377
  )
1518
1378
 
@@ -1542,19 +1402,19 @@ class JsonSchemaParser(Parser):
1542
1402
  self.results.append(data_model_root_type)
1543
1403
  return self.data_type(reference=reference)
1544
1404
 
1545
- def _get_ref_body(self, resolved_ref: str) -> Dict[Any, Any]:
1405
+ def _get_ref_body(self, resolved_ref: str) -> dict[Any, Any]:
1546
1406
  if is_url(resolved_ref):
1547
1407
  return self._get_ref_body_from_url(resolved_ref)
1548
1408
  return self._get_ref_body_from_remote(resolved_ref)
1549
1409
 
1550
- def _get_ref_body_from_url(self, ref: str) -> Dict[Any, Any]:
1551
- # URL Reference $ref: 'http://path/to/your/resource' Uses the whole document located on the different server.
1410
+ def _get_ref_body_from_url(self, ref: str) -> dict[Any, Any]:
1411
+ # URL Reference: $ref: 'http://path/to/your/resource' Uses the whole document located on the different server.
1552
1412
  return self.remote_object_cache.get_or_put(
1553
1413
  ref, default_factory=lambda key: load_yaml(self._get_text_from_url(key))
1554
1414
  )
1555
1415
 
1556
- def _get_ref_body_from_remote(self, resolved_ref: str) -> Dict[Any, Any]:
1557
- # Remote Reference $ref: 'document.json' Uses the whole document located on the same server and in
1416
+ def _get_ref_body_from_remote(self, resolved_ref: str) -> dict[Any, Any]:
1417
+ # Remote Reference: $ref: 'document.json' Uses the whole document located on the same server and in
1558
1418
  # the same location. TODO treat edge case
1559
1419
  full_path = self.base_path / resolved_ref
1560
1420
 
@@ -1571,46 +1431,45 @@ class JsonSchemaParser(Parser):
1571
1431
  # https://swagger.io/docs/specification/using-ref/
1572
1432
  ref = self.model_resolver.resolve_ref(object_ref)
1573
1433
  if get_ref_type(object_ref) == JSONReference.LOCAL:
1574
- # Local Reference $ref: '#/definitions/myElement'
1575
- self.reserved_refs[tuple(self.model_resolver.current_root)].add(ref) # type: ignore
1434
+ # Local Reference: $ref: '#/definitions/myElement'
1435
+ self.reserved_refs[tuple(self.model_resolver.current_root)].add(ref)
1576
1436
  return reference
1577
- elif self.model_resolver.is_after_load(ref):
1578
- self.reserved_refs[tuple(ref.split('#')[0].split('/'))].add(ref) # type: ignore
1437
+ if self.model_resolver.is_after_load(ref):
1438
+ self.reserved_refs[tuple(ref.split("#")[0].split("/"))].add(ref)
1579
1439
  return reference
1580
1440
 
1581
1441
  if is_url(ref):
1582
- relative_path, object_path = ref.split('#')
1442
+ relative_path, object_path = ref.split("#")
1583
1443
  relative_paths = [relative_path]
1584
1444
  base_path = None
1585
1445
  else:
1586
1446
  if self.model_resolver.is_external_root_ref(ref):
1587
- relative_path, object_path = ref[:-1], ''
1447
+ relative_path, object_path = ref[:-1], ""
1588
1448
  else:
1589
- relative_path, object_path = ref.split('#')
1590
- relative_paths = relative_path.split('/')
1449
+ relative_path, object_path = ref.split("#")
1450
+ relative_paths = relative_path.split("/")
1591
1451
  base_path = Path(*relative_paths).parent
1592
- with self.model_resolver.current_base_path_context(
1593
- base_path
1594
- ), self.model_resolver.base_url_context(relative_path):
1452
+ with self.model_resolver.current_base_path_context(base_path), self.model_resolver.base_url_context(
1453
+ relative_path
1454
+ ):
1595
1455
  self._parse_file(
1596
1456
  self._get_ref_body(relative_path),
1597
1457
  self.model_resolver.add_ref(ref, resolved=True).name,
1598
1458
  relative_paths,
1599
- object_path.split('/') if object_path else None,
1459
+ object_path.split("/") if object_path else None,
1600
1460
  )
1601
1461
  reference.loaded = True
1602
1462
  return reference
1603
1463
 
1604
- def parse_ref(self, obj: JsonSchemaObject, path: List[str]) -> None:
1464
+ def parse_ref(self, obj: JsonSchemaObject, path: list[str]) -> None: # noqa: PLR0912
1605
1465
  if obj.ref:
1606
1466
  self.resolve_ref(obj.ref)
1607
1467
  if obj.items:
1608
1468
  if isinstance(obj.items, JsonSchemaObject):
1609
1469
  self.parse_ref(obj.items, path)
1610
- else:
1611
- if isinstance(obj.items, list):
1612
- for item in obj.items:
1613
- self.parse_ref(item, path)
1470
+ elif isinstance(obj.items, list):
1471
+ for item in obj.items:
1472
+ self.parse_ref(item, path)
1614
1473
  if isinstance(obj.additionalProperties, JsonSchemaObject):
1615
1474
  self.parse_ref(obj.additionalProperties, path)
1616
1475
  if obj.patternProperties:
@@ -1627,16 +1486,15 @@ class JsonSchemaParser(Parser):
1627
1486
  if isinstance(property_value, JsonSchemaObject):
1628
1487
  self.parse_ref(property_value, path)
1629
1488
 
1630
- def parse_id(self, obj: JsonSchemaObject, path: List[str]) -> None:
1489
+ def parse_id(self, obj: JsonSchemaObject, path: list[str]) -> None: # noqa: PLR0912
1631
1490
  if obj.id:
1632
1491
  self.model_resolver.add_id(obj.id, path)
1633
1492
  if obj.items:
1634
1493
  if isinstance(obj.items, JsonSchemaObject):
1635
1494
  self.parse_id(obj.items, path)
1636
- else:
1637
- if isinstance(obj.items, list):
1638
- for item in obj.items:
1639
- self.parse_id(item, path)
1495
+ elif isinstance(obj.items, list):
1496
+ for item in obj.items:
1497
+ self.parse_id(item, path)
1640
1498
  if isinstance(obj.additionalProperties, JsonSchemaObject):
1641
1499
  self.parse_id(obj.additionalProperties, path)
1642
1500
  if obj.patternProperties:
@@ -1652,18 +1510,18 @@ class JsonSchemaParser(Parser):
1652
1510
  self.parse_id(property_value, path)
1653
1511
 
1654
1512
  @contextmanager
1655
- def root_id_context(self, root_raw: Dict[str, Any]) -> Generator[None, None, None]:
1656
- root_id: Optional[str] = root_raw.get('$id')
1657
- previous_root_id: Optional[str] = self.root_id
1658
- self.root_id = root_id if root_id else None
1513
+ def root_id_context(self, root_raw: dict[str, Any]) -> Generator[None, None, None]:
1514
+ root_id: str | None = root_raw.get("$id")
1515
+ previous_root_id: str | None = self.root_id
1516
+ self.root_id = root_id or None
1659
1517
  yield
1660
1518
  self.root_id = previous_root_id
1661
1519
 
1662
1520
  def parse_raw_obj(
1663
1521
  self,
1664
1522
  name: str,
1665
- raw: Dict[str, Any],
1666
- path: List[str],
1523
+ raw: dict[str, Any],
1524
+ path: list[str],
1667
1525
  ) -> None:
1668
1526
  self.parse_obj(name, self.SCHEMA_OBJECT_TYPE.parse_obj(raw), path)
1669
1527
 
@@ -1671,7 +1529,7 @@ class JsonSchemaParser(Parser):
1671
1529
  self,
1672
1530
  name: str,
1673
1531
  obj: JsonSchemaObject,
1674
- path: List[str],
1532
+ path: list[str],
1675
1533
  ) -> None:
1676
1534
  if obj.is_array:
1677
1535
  self.parse_array(name, obj, path)
@@ -1685,7 +1543,7 @@ class JsonSchemaParser(Parser):
1685
1543
  self.parse_object(name, obj, path)
1686
1544
  elif obj.patternProperties:
1687
1545
  self.parse_root_type(name, obj, path)
1688
- elif obj.type == 'object':
1546
+ elif obj.type == "object":
1689
1547
  self.parse_object(name, obj, path)
1690
1548
  elif obj.enum and not self.should_parse_enum_as_literal(obj):
1691
1549
  self.parse_enum(name, obj, path)
@@ -1693,14 +1551,11 @@ class JsonSchemaParser(Parser):
1693
1551
  self.parse_root_type(name, obj, path)
1694
1552
  self.parse_ref(obj, path)
1695
1553
 
1696
- def _get_context_source_path_parts(self) -> Iterator[Tuple[Source, List[str]]]:
1697
- if isinstance(self.source, list) or (
1698
- isinstance(self.source, Path) and self.source.is_dir()
1699
- ):
1554
+ def _get_context_source_path_parts(self) -> Iterator[tuple[Source, list[str]]]:
1555
+ if isinstance(self.source, list) or (isinstance(self.source, Path) and self.source.is_dir()):
1700
1556
  self.current_source_path = Path()
1701
1557
  self.model_resolver.after_load_files = {
1702
- self.base_path.joinpath(s.path).resolve().as_posix()
1703
- for s in self.iter_source
1558
+ self.base_path.joinpath(s.path).resolve().as_posix() for s in self.iter_source
1704
1559
  }
1705
1560
 
1706
1561
  for source in self.iter_source:
@@ -1719,16 +1574,16 @@ class JsonSchemaParser(Parser):
1719
1574
  for source, path_parts in self._get_context_source_path_parts():
1720
1575
  self.raw_obj = load_yaml(source.text)
1721
1576
  if self.raw_obj is None: # pragma: no cover
1722
- warn(f'{source.path} is empty. Skipping this file')
1577
+ warn(f"{source.path} is empty. Skipping this file", stacklevel=2)
1723
1578
  continue
1724
1579
  if self.custom_class_name_generator:
1725
- obj_name = self.raw_obj.get('title', 'Model')
1580
+ obj_name = self.raw_obj.get("title", "Model")
1726
1581
  else:
1727
1582
  if self.class_name:
1728
1583
  obj_name = self.class_name
1729
1584
  else:
1730
1585
  # backward compatible
1731
- obj_name = self.raw_obj.get('title', 'Model')
1586
+ obj_name = self.raw_obj.get("title", "Model")
1732
1587
  if not self.model_resolver.validate_name(obj_name):
1733
1588
  obj_name = title_to_class_name(obj_name)
1734
1589
  if not self.model_resolver.validate_name(obj_name):
@@ -1741,7 +1596,7 @@ class JsonSchemaParser(Parser):
1741
1596
  model_count: int = len(self.results)
1742
1597
  for source in self.iter_source:
1743
1598
  path_parts = list(source.path.parts)
1744
- reserved_refs = self.reserved_refs.get(tuple(path_parts)) # type: ignore
1599
+ reserved_refs = self.reserved_refs.get(tuple(path_parts))
1745
1600
  if not reserved_refs:
1746
1601
  continue
1747
1602
  if self.current_source_path is not None:
@@ -1761,45 +1616,36 @@ class JsonSchemaParser(Parser):
1761
1616
  # New model have been generated. It try to resolve json pointer again.
1762
1617
  self._resolve_unparsed_json_pointer()
1763
1618
 
1764
- def parse_json_pointer(
1765
- self, raw: Dict[str, Any], ref: str, path_parts: List[str]
1766
- ) -> None:
1767
- path = ref.split('#', 1)[-1]
1768
- if path[0] == '/': # pragma: no cover
1619
+ def parse_json_pointer(self, raw: dict[str, Any], ref: str, path_parts: list[str]) -> None:
1620
+ path = ref.split("#", 1)[-1]
1621
+ if path[0] == "/": # pragma: no cover
1769
1622
  path = path[1:]
1770
- object_paths = path.split('/')
1623
+ object_paths = path.split("/")
1771
1624
  models = get_model_by_path(raw, object_paths)
1772
1625
  model_name = object_paths[-1]
1773
1626
 
1774
- self.parse_raw_obj(
1775
- model_name, models, [*path_parts, f'#/{object_paths[0]}', *object_paths[1:]]
1776
- )
1627
+ self.parse_raw_obj(model_name, models, [*path_parts, f"#/{object_paths[0]}", *object_paths[1:]])
1777
1628
 
1778
- def _parse_file(
1629
+ def _parse_file( # noqa: PLR0912
1779
1630
  self,
1780
- raw: Dict[str, Any],
1631
+ raw: dict[str, Any],
1781
1632
  obj_name: str,
1782
- path_parts: List[str],
1783
- object_paths: Optional[List[str]] = None,
1633
+ path_parts: list[str],
1634
+ object_paths: list[str] | None = None,
1784
1635
  ) -> None:
1785
1636
  object_paths = [o for o in object_paths or [] if o]
1786
- if object_paths:
1787
- path = [*path_parts, f'#/{object_paths[0]}', *object_paths[1:]]
1788
- else:
1789
- path = path_parts
1637
+ path = [*path_parts, f"#/{object_paths[0]}", *object_paths[1:]] if object_paths else path_parts
1790
1638
  with self.model_resolver.current_root_context(path_parts):
1791
- obj_name = self.model_resolver.add(
1792
- path, obj_name, unique=False, class_name=True
1793
- ).name
1639
+ obj_name = self.model_resolver.add(path, obj_name, unique=False, class_name=True).name
1794
1640
  with self.root_id_context(raw):
1795
1641
  # Some jsonschema docs include attribute self to have include version details
1796
- raw.pop('self', None)
1642
+ raw.pop("self", None)
1797
1643
  # parse $id before parsing $ref
1798
1644
  root_obj = self.SCHEMA_OBJECT_TYPE.parse_obj(raw)
1799
1645
  self.parse_id(root_obj, path_parts)
1800
- definitions: Optional[Dict[Any, Any]] = None
1801
- schema_path = ''
1802
- for schema_path, split_schema_path in self.schema_paths:
1646
+ definitions: dict[Any, Any] | None = None
1647
+ _schema_path = ""
1648
+ for _schema_path, split_schema_path in self.schema_paths:
1803
1649
  try:
1804
1650
  definitions = get_model_by_path(raw, split_schema_path)
1805
1651
  if definitions:
@@ -1811,18 +1657,16 @@ class JsonSchemaParser(Parser):
1811
1657
 
1812
1658
  for key, model in definitions.items():
1813
1659
  obj = self.SCHEMA_OBJECT_TYPE.parse_obj(model)
1814
- self.parse_id(obj, [*path_parts, schema_path, key])
1660
+ self.parse_id(obj, [*path_parts, _schema_path, key])
1815
1661
 
1816
1662
  if object_paths:
1817
1663
  models = get_model_by_path(raw, object_paths)
1818
1664
  model_name = object_paths[-1]
1819
- self.parse_obj(
1820
- model_name, self.SCHEMA_OBJECT_TYPE.parse_obj(models), path
1821
- )
1665
+ self.parse_obj(model_name, self.SCHEMA_OBJECT_TYPE.parse_obj(models), path)
1822
1666
  else:
1823
- self.parse_obj(obj_name, root_obj, path_parts or ['#'])
1667
+ self.parse_obj(obj_name, root_obj, path_parts or ["#"])
1824
1668
  for key, model in definitions.items():
1825
- path = [*path_parts, schema_path, key]
1669
+ path = [*path_parts, _schema_path, key]
1826
1670
  reference = self.model_resolver.get(path)
1827
1671
  if not reference or not reference.loaded:
1828
1672
  self.parse_raw_obj(key, model, path)
@@ -1834,13 +1678,11 @@ class JsonSchemaParser(Parser):
1834
1678
  reference = self.model_resolver.get(reserved_path)
1835
1679
  if not reference or reference.loaded:
1836
1680
  continue
1837
- object_paths = reserved_path.split('#/', 1)[-1].split('/')
1838
- path = reserved_path.split('/')
1681
+ object_paths = reserved_path.split("#/", 1)[-1].split("/")
1682
+ path = reserved_path.split("/")
1839
1683
  models = get_model_by_path(raw, object_paths)
1840
1684
  model_name = object_paths[-1]
1841
- self.parse_obj(
1842
- model_name, self.SCHEMA_OBJECT_TYPE.parse_obj(models), path
1843
- )
1685
+ self.parse_obj(model_name, self.SCHEMA_OBJECT_TYPE.parse_obj(models), path)
1844
1686
  previous_reserved_refs = reserved_refs
1845
1687
  reserved_refs = set(self.reserved_refs.get(key) or [])
1846
1688
  if previous_reserved_refs == reserved_refs: