Skip to content

Commit 0f79b4d

Browse files
committed
Add GenerateConfig lazy import from top-level module
1 parent 4cbf3bf commit 0f79b4d

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

docs/using_as_module.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ pip install 'datamodel-code-generator[http]'
1616

1717
When the `output` parameter is omitted (or set to `None`), `generate()` returns the generated code directly as a string:
1818

19+
!!! note
20+
`GenerateConfig` is only available in Pydantic v2 environments.
21+
For Pydantic v1, use `from datamodel_code_generator.config import GenerateConfig`
22+
and call `update_forward_refs()` before use.
23+
1924
```python
2025
from datamodel_code_generator import InputFileType, generate, GenerateConfig, DataModelType
2126

src/datamodel_code_generator/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,13 +971,21 @@ def infer_input_type(text: str) -> InputFileType:
971971
"detect_jsonschema_version": "datamodel_code_generator.parser.schema_version",
972972
"detect_openapi_version": "datamodel_code_generator.parser.schema_version",
973973
"generate_dynamic_models": "datamodel_code_generator.dynamic",
974+
"GenerateConfig": "datamodel_code_generator.config",
974975
}
975976

976977

977978
def __getattr__(name: str) -> Any:
978979
if name in _LAZY_IMPORTS:
979980
import importlib # noqa: PLC0415
980981

982+
if name == "GenerateConfig" and not is_pydantic_v2(): # pragma: no cover
983+
msg = (
984+
f"'{name}' is only available in Pydantic v2 environments. "
985+
"Use 'from datamodel_code_generator.config import GenerateConfig' instead."
986+
)
987+
raise ImportError(msg)
988+
981989
module = importlib.import_module(_LAZY_IMPORTS[name])
982990
return getattr(module, name)
983991
msg = f"module {__name__!r} has no attribute {name!r}"
@@ -1025,3 +1033,6 @@ def __getattr__(name: str) -> Any:
10251033
"generate",
10261034
"generate_dynamic_models", # noqa: F822
10271035
]
1036+
1037+
if is_pydantic_v2(): # pragma: no cover
1038+
__all__ += ["GenerateConfig"]

tests/main/test_main_general.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import pytest
1212
from inline_snapshot import snapshot
1313

14+
import datamodel_code_generator
1415
from datamodel_code_generator import (
1516
AllExportsScope,
1617
DataModelType,
@@ -28,6 +29,7 @@
2829
from datamodel_code_generator.format import CodeFormatter, PythonVersion
2930
from datamodel_code_generator.model.pydantic_v2 import UnionMode
3031
from datamodel_code_generator.parser.openapi import OpenAPIParser
32+
from datamodel_code_generator.util import is_pydantic_v2
3133
from tests.conftest import assert_output, create_assert_file_content, freeze_time
3234
from tests.main.conftest import (
3335
DATA_PATH,
@@ -2307,3 +2309,34 @@ def test_use_annotated_no_warning_pydantic_v1(output_file: Path) -> None:
23072309
extra_args=["--output-model-type", "pydantic.BaseModel"],
23082310
)
23092311
assert not any("--use-annotated will be enabled" in str(warning.message) for warning in w)
2312+
2313+
2314+
@pytest.mark.skipif(not is_pydantic_v2(), reason="GenerateConfig requires Pydantic v2")
2315+
def test_import_generate_config_from_top_level() -> None:
2316+
"""Test that GenerateConfig can be imported from top-level module."""
2317+
from datamodel_code_generator import GenerateConfig as TopLevelGenerateConfig
2318+
2319+
assert TopLevelGenerateConfig is not None
2320+
assert TopLevelGenerateConfig is GenerateConfig
2321+
2322+
2323+
@pytest.mark.skipif(not is_pydantic_v2(), reason="GenerateConfig requires Pydantic v2")
2324+
def test_generate_with_imported_config_from_top_level() -> None:
2325+
"""Test generate() with GenerateConfig imported from top-level."""
2326+
config = datamodel_code_generator.GenerateConfig(class_name="TestModel")
2327+
result = generate('{"type": "object"}', config=config)
2328+
assert result is not None
2329+
assert "class TestModel" in result
2330+
2331+
2332+
@pytest.mark.skipif(not is_pydantic_v2(), reason="GenerateConfig requires Pydantic v2")
2333+
def test_all_exports_includes_generate_config() -> None:
2334+
"""Test that __all__ includes GenerateConfig in Pydantic v2."""
2335+
assert "GenerateConfig" in datamodel_code_generator.__all__
2336+
2337+
2338+
@pytest.mark.skipif(is_pydantic_v2(), reason="Test for Pydantic v1 only")
2339+
def test_import_generate_config_fails_on_v1() -> None:
2340+
"""GenerateConfig should not be importable from top-level in Pydantic v1."""
2341+
with pytest.raises(ImportError, match="only available in Pydantic v2"):
2342+
_ = datamodel_code_generator.GenerateConfig

0 commit comments

Comments
 (0)