@@ -296,3 +296,94 @@ class Model(BaseModel):
296296 ) as package :
297297 assert "pydantic-field" in package ["Model.field" ].labels
298298 assert "pydantic-field" not in package ["Model._private" ].labels
299+
300+
301+ def test_field_description_with_dedent () -> None :
302+ """Test that field descriptions wrapped in textwrap.dedent() are extracted."""
303+ code = """
304+ from textwrap import dedent
305+ from pydantic import BaseModel, Field
306+
307+ class Model(BaseModel):
308+ field1: int = Field(
309+ description=dedent('''
310+ This is a multiline description.
311+ With multiple lines.
312+ ''')
313+ )
314+ field2: str = Field(default="test", description=dedent("Single line dedented."))
315+ """
316+ with temporary_visited_package (
317+ "package" ,
318+ modules = {"__init__.py" : code },
319+ extensions = Extensions (PydanticExtension (schema = False )),
320+ ) as package :
321+ assert package ["Model.field1" ].is_attribute
322+ assert "pydantic-field" in package ["Model.field1" ].labels
323+ assert package ["Model.field1" ].docstring is not None
324+ assert "This is a multiline description." in package ["Model.field1" ].docstring .value
325+ assert "With multiple lines." in package ["Model.field1" ].docstring .value
326+
327+ assert package ["Model.field2" ].is_attribute
328+ assert "pydantic-field" in package ["Model.field2" ].labels
329+ assert package ["Model.field2" ].docstring is not None
330+ assert package ["Model.field2" ].docstring .value == "Single line dedented."
331+
332+
333+ def test_field_description_with_cleandoc () -> None :
334+ """Test that field descriptions wrapped in inspect.cleandoc() are extracted."""
335+ code = """
336+ from inspect import cleandoc
337+ from pydantic import BaseModel, Field
338+
339+ class Model(BaseModel):
340+ field1: int = Field(
341+ description=cleandoc('''
342+ This is a multiline description.
343+ With multiple lines.
344+ ''')
345+ )
346+ field2: str = Field(default="test", description=cleandoc("Single line cleandoc."))
347+ """
348+ with temporary_visited_package (
349+ "package" ,
350+ modules = {"__init__.py" : code },
351+ extensions = Extensions (PydanticExtension (schema = False )),
352+ ) as package :
353+ assert package ["Model.field1" ].is_attribute
354+ assert "pydantic-field" in package ["Model.field1" ].labels
355+ assert package ["Model.field1" ].docstring is not None
356+ assert "This is a multiline description." in package ["Model.field1" ].docstring .value
357+ assert "With multiple lines." in package ["Model.field1" ].docstring .value
358+
359+ assert package ["Model.field2" ].is_attribute
360+ assert "pydantic-field" in package ["Model.field2" ].labels
361+ assert package ["Model.field2" ].docstring is not None
362+ assert package ["Model.field2" ].docstring .value == "Single line cleandoc."
363+
364+
365+ def test_field_description_with_annotated_and_dedent () -> None :
366+ """Test that field descriptions with Annotated and dedent() are extracted."""
367+ code = """
368+ from textwrap import dedent
369+ from pydantic import BaseModel, Field
370+ from typing import Annotated
371+
372+ class Model(BaseModel):
373+ field1: Annotated[int, Field(
374+ description=dedent('''
375+ This is a multiline description.
376+ With multiple lines.
377+ ''')
378+ )]
379+ """
380+ with temporary_visited_package (
381+ "package" ,
382+ modules = {"__init__.py" : code },
383+ extensions = Extensions (PydanticExtension (schema = False )),
384+ ) as package :
385+ assert package ["Model.field1" ].is_attribute
386+ assert "pydantic-field" in package ["Model.field1" ].labels
387+ assert package ["Model.field1" ].docstring is not None
388+ assert "This is a multiline description." in package ["Model.field1" ].docstring .value
389+ assert "With multiple lines." in package ["Model.field1" ].docstring .value
0 commit comments