@@ -56,7 +56,7 @@ def leave_ClassDef(self, original_node: cst.ClassDef, updated_node: cst.ClassDef
56
56
self .inside_base_model = False
57
57
return updated_node
58
58
59
- def visit_AnnAssign (self , node : cst .AnnAssign ) -> bool | None :
59
+ def visit_AnnAssign (self , node : cst .AnnAssign ) -> None :
60
60
if m .matches (
61
61
node .annotation .annotation ,
62
62
m .Subscript (m .Name ("Optional" ) | m .Attribute (m .Name ("typing" ), m .Name ("Optional" )))
@@ -75,11 +75,29 @@ def visit_AnnAssign(self, node: cst.AnnAssign) -> bool | None:
75
75
| m .BinaryOperation (operator = m .BitOr (), right = m .Name ("None" )),
76
76
):
77
77
self .should_add_none = True
78
- return super (). visit_AnnAssign ( node )
78
+ return None
79
79
80
80
def leave_AnnAssign (self , original_node : cst .AnnAssign , updated_node : cst .AnnAssign ) -> cst .AnnAssign :
81
- if self .inside_base_model and self .should_add_none and updated_node .value is None :
82
- updated_node = updated_node .with_changes (value = cst .Name ("None" ))
81
+ if self .inside_base_model and self .should_add_none :
82
+ if updated_node .value is None :
83
+ updated_node = updated_node .with_changes (value = cst .Name ("None" ))
84
+ # TODO: Should accept `pydantic.Field` as well.
85
+ elif m .matches (updated_node .value , m .Call (func = m .Name ("Field" ))):
86
+ assert isinstance (updated_node .value , cst .Call )
87
+ if updated_node .value .args :
88
+ arg = updated_node .value .args [0 ]
89
+ if (arg .keyword is None or arg .keyword .value == "default" ) and m .matches (arg .value , m .Ellipsis ()):
90
+ updated_node = updated_node .with_changes (
91
+ value = updated_node .value .with_changes (
92
+ args = [arg .with_changes (value = cst .Name ("None" )), * updated_node .value .args [1 :]]
93
+ )
94
+ )
95
+ # This is the case where `Field` is called without any arguments e.g. `Field()`.
96
+ else :
97
+ updated_node = updated_node .with_changes (
98
+ value = updated_node .value .with_changes (args = [cst .Arg (value = cst .Name ("None" ))]) # type: ignore
99
+ )
100
+
83
101
self .inside_an_assign = False
84
102
self .should_add_none = False
85
103
return updated_node
0 commit comments