Skip to content

Commit 2b45def

Browse files
authored
Add FutureWarning for upcoming ruff default formatters (#2895)
1 parent a834e62 commit 2b45def

12 files changed

Lines changed: 86 additions & 18 deletions

File tree

docs/formatting.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ Generated code is automatically formatted using code formatters. By default, `bl
66

77
## 🎯 Default Behavior
88

9+
!!! warning "Future Change"
10+
In a future version, the default formatters will change from `black` and `isort` to `ruff`.
11+
To prepare for this change, consider switching to ruff now using `--formatters ruff-format ruff-check`.
12+
13+
**CLI users**: To suppress this warning, use `--disable-warnings` or explicitly specify `--formatters black isort`.
14+
15+
**Library users**: Explicitly pass `formatters=[Formatter.BLACK, Formatter.ISORT]` to suppress this warning.
16+
917
```bash
1018
datamodel-codegen --input schema.yaml --output model.py
1119
```
@@ -28,6 +36,12 @@ This runs the following formatters in order:
2836

2937
[Ruff](https://github.com/astral-sh/ruff) is a fast Python linter and formatter. To use it:
3038

39+
!!! note "Installation Required"
40+
ruff is an optional dependency. Install it with:
41+
```bash
42+
pip install 'datamodel-code-generator[ruff]'
43+
```
44+
3145
```bash
3246
# Use ruff for both linting and formatting
3347
datamodel-codegen --formatters ruff-check ruff-format --input schema.yaml --output model.py

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ filterwarnings = [
223223
"ignore:^.*No schemas found in components/schemas.*",
224224
"ignore:^.*Dataclass .* has a field ordering conflict due to inheritance.*:UserWarning",
225225
"ignore:^.*is empty or not a dict. Skipping this file.*:UserWarning",
226+
"ignore:^.*The default formatters.*:FutureWarning",
226227
]
227228
norecursedirs = [ "tests/data/*", ".tox" ]
228229
verbosity_assertions = 2

src/datamodel_code_generator/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,11 @@ def get_header_and_first_line(csv_file: IO[str]) -> dict[str, Any]:
879879

880880
file.close()
881881

882-
if defer_formatting and (Formatter.RUFF_CHECK in config.formatters or Formatter.RUFF_FORMAT in config.formatters):
882+
if (
883+
defer_formatting
884+
and config.formatters
885+
and (Formatter.RUFF_CHECK in config.formatters or Formatter.RUFF_FORMAT in config.formatters)
886+
):
883887
code_formatter = CodeFormatter(
884888
config.target_python_version,
885889
config.settings_path,

src/datamodel_code_generator/__main__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474
)
7575
from datamodel_code_generator.arguments import DEFAULT_ENCODING, arg_parser, namespace
7676
from datamodel_code_generator.format import (
77-
DEFAULT_FORMATTERS,
7877
DateClassType,
7978
DatetimeClassType,
8079
Formatter,
@@ -595,7 +594,7 @@ def validate_class_name_affix_scope(cls, v: str | ClassNameAffixScope | None) ->
595594
no_alias: bool = False
596595
use_frozen_field: bool = False
597596
use_default_factory_for_optional_nested_models: bool = False
598-
formatters: list[Formatter] = DEFAULT_FORMATTERS
597+
formatters: list[Formatter] | None = None
599598
parent_scoped_naming: bool = False
600599
naming_strategy: Optional[NamingStrategy] = None # noqa: UP045
601600
duplicate_name_suffix: Optional[dict[str, str]] = None # noqa: UP045

src/datamodel_code_generator/_types/generate_config_dict.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ class GenerateConfigDict(TypedDict):
147147
no_alias: NotRequired[bool]
148148
use_frozen_field: NotRequired[bool]
149149
use_default_factory_for_optional_nested_models: NotRequired[bool]
150-
formatters: NotRequired[list[Formatter]]
150+
formatters: NotRequired[list[Formatter] | None]
151151
settings_path: NotRequired[Path | None]
152152
parent_scoped_naming: NotRequired[bool]
153153
naming_strategy: NotRequired[NamingStrategy | None]

src/datamodel_code_generator/_types/parser_config_dicts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class ParserConfigDict(TypedDict):
136136
no_alias: NotRequired[bool]
137137
use_frozen_field: NotRequired[bool]
138138
use_default_factory_for_optional_nested_models: NotRequired[bool]
139-
formatters: NotRequired[list[Formatter]]
139+
formatters: NotRequired[list[Formatter] | None]
140140
defer_formatting: NotRequired[bool]
141141
parent_scoped_naming: NotRequired[bool]
142142
naming_strategy: NotRequired[NamingStrategy | None]

src/datamodel_code_generator/config.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
TargetPydanticVersion,
3131
)
3232
from datamodel_code_generator.format import (
33-
DEFAULT_FORMATTERS,
3433
DateClassType,
3534
DatetimeClassType,
3635
Formatter,
@@ -185,7 +184,7 @@ class Config:
185184
no_alias: bool = False
186185
use_frozen_field: bool = False
187186
use_default_factory_for_optional_nested_models: bool = False
188-
formatters: list[Formatter] = DEFAULT_FORMATTERS
187+
formatters: list[Formatter] | None = None
189188
settings_path: Path | None = None
190189
parent_scoped_naming: bool = False
191190
naming_strategy: NamingStrategy | None = None
@@ -318,7 +317,7 @@ class Config:
318317
no_alias: bool = False
319318
use_frozen_field: bool = False
320319
use_default_factory_for_optional_nested_models: bool = False
321-
formatters: list[Formatter] = DEFAULT_FORMATTERS
320+
formatters: list[Formatter] | None = None
322321
defer_formatting: bool = False
323322
parent_scoped_naming: bool = False
324323
naming_strategy: NamingStrategy | None = None

src/datamodel_code_generator/format.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,21 @@ def __init__( # noqa: PLR0912, PLR0913, PLR0915, PLR0917
193193
custom_formatters: list[str] | None = None,
194194
custom_formatters_kwargs: dict[str, Any] | None = None,
195195
encoding: str = "utf-8",
196-
formatters: list[Formatter] = DEFAULT_FORMATTERS,
196+
formatters: list[Formatter] | None = None,
197197
defer_formatting: bool = False, # noqa: FBT001, FBT002
198198
) -> None:
199199
"""Initialize code formatter with configuration for black, isort, ruff, and custom formatters."""
200+
if formatters is None:
201+
warn(
202+
"The default formatters (black, isort) will be replaced by ruff in a future version. "
203+
"To prepare for this change, consider using: formatters=[Formatter.RUFF_FORMAT, Formatter.RUFF_CHECK]. "
204+
"Install ruff with: pip install 'datamodel-code-generator[ruff]'. "
205+
"To suppress this warning, specify formatters explicitly.",
206+
FutureWarning,
207+
stacklevel=2,
208+
)
209+
formatters = list(DEFAULT_FORMATTERS)
210+
200211
if not settings_path:
201212
settings_path = Path.cwd()
202213
elif settings_path.is_file():

src/datamodel_code_generator/parser/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@ def __init__( # noqa: PLR0912, PLR0915
928928
self.custom_formatters_kwargs = config.custom_formatters_kwargs
929929
self.treat_dot_as_module = config.treat_dot_as_module
930930
self.default_field_extras: dict[str, Any] | None = config.default_field_extras
931-
self.formatters: list[Formatter] = config.formatters
931+
self.formatters: list[Formatter] | None = config.formatters
932932
self.defer_formatting: bool = config.defer_formatting
933933
self.type_mappings: dict[tuple[str, str], str] = Parser._parse_type_mappings(config.type_mappings)
934934
self.type_overrides: dict[str, str] = config.type_overrides or {}

tests/data/expected/main/input_model/config_class.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ class GenerateConfig(TypedDict):
222222
no_alias: NotRequired[bool]
223223
use_frozen_field: NotRequired[bool]
224224
use_default_factory_for_optional_nested_models: NotRequired[bool]
225-
formatters: NotRequired[list[Formatter]]
225+
formatters: NotRequired[list[Formatter] | None]
226226
settings_path: NotRequired[str | None]
227227
parent_scoped_naming: NotRequired[bool]
228228
naming_strategy: NotRequired[NamingStrategy | None]

0 commit comments

Comments
 (0)