typantic 0.2.0__tar.gz → 0.2.1__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: typantic
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Auto-generate Typer CLI interfaces from Pydantic models.
5
5
  Keywords: typer,pydantic,cli,validation
6
6
  Author: Kilian Schnelle
@@ -99,7 +99,7 @@ $ python example.py --help
99
99
  ╭─ Options ────────────────────────────────────────────────────╮
100
100
  │ * --output PATH Output directory. [required] │
101
101
  │ --threshold FLOAT Detection threshold. [default: 0.5]│
102
- │ --seed INTEGER Random seed.
102
+ │ --seed INTEGER Random seed. [default: (None)]
103
103
  │ --help Show this message and exit. │
104
104
  ╰──────────────────────────────────────────────────────────────╯
105
105
  ```
@@ -126,6 +126,7 @@ Your function receives the **validated model instance** — validators, `default
126
126
  | `Field(default=...)` | Default value shown in `--help` |
127
127
  | `Field(default_factory=...)` | Factory called once at decoration time |
128
128
  | `int \| None` | Optional CLI option |
129
+ | `default=None` | Rendered as `[default: (None)]` |
129
130
  | `list[Path]` | Variadic positional argument |
130
131
  | `AfterValidator`, `BeforeValidator` | Run at call time via Pydantic |
131
132
 
@@ -75,7 +75,7 @@ $ python example.py --help
75
75
  ╭─ Options ────────────────────────────────────────────────────╮
76
76
  │ * --output PATH Output directory. [required] │
77
77
  │ --threshold FLOAT Detection threshold. [default: 0.5]│
78
- │ --seed INTEGER Random seed.
78
+ │ --seed INTEGER Random seed. [default: (None)]
79
79
  │ --help Show this message and exit. │
80
80
  ╰──────────────────────────────────────────────────────────────╯
81
81
  ```
@@ -102,6 +102,7 @@ Your function receives the **validated model instance** — validators, `default
102
102
  | `Field(default=...)` | Default value shown in `--help` |
103
103
  | `Field(default_factory=...)` | Factory called once at decoration time |
104
104
  | `int \| None` | Optional CLI option |
105
+ | `default=None` | Rendered as `[default: (None)]` |
105
106
  | `list[Path]` | Variadic positional argument |
106
107
  | `AfterValidator`, `BeforeValidator` | Run at call time via Pydantic |
107
108
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "typantic"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "Auto-generate Typer CLI interfaces from Pydantic models."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -93,6 +93,8 @@ def pydantic_to_typer(
93
93
  - ``Field(default=...)`` -> Typer default value
94
94
  - ``Field(default_factory=...)`` -> factory is called once at
95
95
  decoration time to supply the Typer default
96
+ - a ``None`` default -> rendered as ``[default: (None)]`` in
97
+ ``--help`` (Click would otherwise omit it entirely)
96
98
 
97
99
  The decorated function receives the **validated** Pydantic model
98
100
  instance, so all ``AfterValidator`` / ``BeforeValidator`` logic runs
@@ -134,6 +136,14 @@ def pydantic_to_typer(
134
136
  base_type = _extract_base_type(resolved_hints[name])
135
137
  help_text = field_info.description or ""
136
138
 
139
+ default: object
140
+ if field_info.is_required():
141
+ default = inspect.Parameter.empty
142
+ elif field_info.default_factory is not None:
143
+ default = field_info.default_factory() # type: ignore[call-arg]
144
+ else:
145
+ default = field_info.default
146
+
137
147
  typer_meta: typer.models.ArgumentInfo | typer.models.OptionInfo
138
148
  if field_info.kw_only is False:
139
149
  typer_meta = typer.Argument(
@@ -142,19 +152,17 @@ def pydantic_to_typer(
142
152
  )
143
153
  else:
144
154
  panel = _panel_for_field(model_cls, name) if subpanels else None
145
- typer_meta = typer.Option(help=help_text, rich_help_panel=panel)
155
+ typer_meta = typer.Option(
156
+ help=help_text,
157
+ rich_help_panel=panel,
158
+ # Click omits `None` defaults entirely; surface them as
159
+ # "[default: (None)]" so optional options are visibly so.
160
+ show_default="None" if default is None else True,
161
+ )
146
162
 
147
163
  annotated = Annotated[base_type, typer_meta] # type: ignore[valid-type]
148
164
  new_annotations[name] = annotated
149
165
 
150
- default: object
151
- if field_info.is_required():
152
- default = inspect.Parameter.empty
153
- elif field_info.default_factory is not None:
154
- default = field_info.default_factory() # type: ignore[call-arg]
155
- else:
156
- default = field_info.default
157
-
158
166
  new_params.append(
159
167
  inspect.Parameter(
160
168
  name,
File without changes