@@ -6397,6 +6397,122 @@ def test_main_jsonschema_additional_properties_self_ref(output_file: Path) -> No
63976397 )
63986398
63996399
6400+ @BLACK_PY314_SKIP
6401+ def test_main_jsonschema_additional_properties_self_ref_target_python_314(output_file: Path) -> None:
6402+ """Test Python 3.14 typed extras keep self-references safe at runtime."""
6403+ run_main_and_assert(
6404+ input_path=JSON_SCHEMA_DATA_PATH / "additional_properties_self_ref.json",
6405+ output_path=output_file,
6406+ input_file_type="jsonschema",
6407+ assert_func=assert_file_content,
6408+ expected_file="additional_properties_self_ref_py314.py",
6409+ extra_args=[
6410+ "--output-model-type",
6411+ "pydantic_v2.BaseModel",
6412+ "--target-python-version",
6413+ "3.14",
6414+ ],
6415+ )
6416+ assert_generated_model_json_validation(
6417+ output_file,
6418+ module_name="additional_properties_self_ref_py314",
6419+ model_name="Node",
6420+ valid_json='{"name":"root","child":{"name":"leaf"}}',
6421+ invalid_json='{"name":"root","child":{"name":"leaf","bad":1}}',
6422+ expected_error_type="model_type",
6423+ expected_attribute_path=("__pydantic_extra__", "child", "name"),
6424+ expected_attribute_value="leaf",
6425+ )
6426+
6427+
6428+ def test_main_jsonschema_additional_properties_scalar_no_future_imports_target_python_313(
6429+ output_file: Path,
6430+ ) -> None:
6431+ """Test typed extras do not hide ordinary fields without deferred annotations."""
6432+ run_main_and_assert(
6433+ input_path=JSON_SCHEMA_DATA_PATH / "additional_properties_schema_with_properties.json",
6434+ output_path=output_file,
6435+ input_file_type="jsonschema",
6436+ assert_func=assert_file_content,
6437+ expected_file="additional_properties_schema_with_properties_py313_no_future_imports.py",
6438+ extra_args=[
6439+ "--output-model-type",
6440+ "pydantic_v2.BaseModel",
6441+ "--target-python-version",
6442+ "3.13",
6443+ "--disable-future-imports",
6444+ ],
6445+ force_exec_validation=True,
6446+ )
6447+ assert_generated_model_json_validation(
6448+ output_file,
6449+ module_name="additional_properties_schema_with_properties_py313_no_future_imports",
6450+ model_name="KnownAndExtra",
6451+ valid_json='{"name":"known","size":1}',
6452+ invalid_json='{"name":"known","size":[]}',
6453+ expected_error_type="int_type",
6454+ expected_attribute_path=("__pydantic_extra__",),
6455+ expected_attribute_value={"size": 1},
6456+ )
6457+
6458+
6459+ def test_main_jsonschema_additional_properties_self_ref_use_union_operator_force_optional(
6460+ output_file: Path,
6461+ ) -> None:
6462+ """Test typed self-references do not rewrite unrelated PEP 604 annotations."""
6463+ run_main_and_assert(
6464+ input_path=JSON_SCHEMA_DATA_PATH / "additional_properties_self_ref.json",
6465+ output_path=output_file,
6466+ input_file_type="jsonschema",
6467+ assert_func=assert_file_content,
6468+ expected_file="additional_properties_self_ref_union_operator_force_optional.py",
6469+ extra_args=[
6470+ "--output-model-type",
6471+ "pydantic_v2.BaseModel",
6472+ "--use-union-operator",
6473+ "--force-optional",
6474+ ],
6475+ force_exec_validation=True,
6476+ )
6477+ assert_generated_model_json_validation(
6478+ output_file,
6479+ module_name="additional_properties_self_ref_union_operator_force_optional",
6480+ model_name="Node",
6481+ valid_json='{"name":"root","child":{"name":"leaf"}}',
6482+ invalid_json='{"name":"root","child":{"name":"leaf","bad":1}}',
6483+ expected_error_type="model_type",
6484+ expected_attribute_path=("__pydantic_extra__", "child", "name"),
6485+ expected_attribute_value="leaf",
6486+ )
6487+
6488+
6489+ def test_main_jsonschema_additional_properties_nullable_self_ref_use_union_operator(output_file: Path) -> None:
6490+ """Test typed-extra forward refs invalidate retained import caches."""
6491+ run_main_and_assert(
6492+ input_path=JSON_SCHEMA_DATA_PATH / "additional_properties_nullable_self_ref.json",
6493+ output_path=output_file,
6494+ input_file_type="jsonschema",
6495+ assert_func=assert_file_content,
6496+ expected_file="additional_properties_nullable_self_ref_union_operator.py",
6497+ extra_args=[
6498+ "--output-model-type",
6499+ "pydantic_v2.BaseModel",
6500+ "--use-union-operator",
6501+ ],
6502+ force_exec_validation=True,
6503+ )
6504+ assert_generated_model_json_validation(
6505+ output_file,
6506+ module_name="additional_properties_nullable_self_ref_union_operator",
6507+ model_name="Node",
6508+ valid_json='{"name":"root","child":{"name":"leaf"},"empty":null}',
6509+ invalid_json='{"name":"root","child":{"name":"leaf","bad":1}}',
6510+ expected_error_type="model_type",
6511+ expected_attribute_path=("__pydantic_extra__", "child", "name"),
6512+ expected_attribute_value="leaf",
6513+ )
6514+
6515+
64006516def test_main_jsonschema_property_names_type_non_string(output_file: Path) -> None:
64016517 """Test non-string propertyNames type rejects every JSON object key."""
64026518 run_main_and_assert(
0 commit comments