From c554fb940a5ecca29cc939c4926d3479f8025344 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 25 Aug 2025 16:24:29 +0200 Subject: [PATCH 01/32] =?UTF-8?q?=E2=9C=A8=20Feat(vuecore/schemas/plotly?= =?UTF-8?q?=5Fbase.py):=20Create=20base=20plotly=20config=20for=20pydantic?= =?UTF-8?q?=20models=20to=20store=20parameters=20shared=20across=20multipl?= =?UTF-8?q?e=20plot=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/schemas/plotly_base.py | 122 +++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/vuecore/schemas/plotly_base.py diff --git a/src/vuecore/schemas/plotly_base.py b/src/vuecore/schemas/plotly_base.py new file mode 100644 index 0000000..a8e704d --- /dev/null +++ b/src/vuecore/schemas/plotly_base.py @@ -0,0 +1,122 @@ +from typing import Dict, List, Optional +from pydantic import BaseModel, Field, ConfigDict, model_validator + + +class PlotlyBaseConfig(BaseModel): + """ + Pydantic model for common Plotly configurations. + + This model serves as a curated API for common parameters of Plotly plots, + closely aligned with the `plotly.express` API + (https://plotly.com/python-api-reference/plotly.express.html). + + This base class includes parameters shared across multiple plot types + to ensure consistency and reduce code repetition. It uses a validator to + enforce that at least one of the x or y axes is provided. Plot-specific + schemas should inherit from this model. + + Attributes + ---------- + -----Data Mapping----- + x : Optional[str] + Column for the x-axis values. + y : Optional[str] + Column for the y-axis values. + color : Optional[str] + Column to assign color to plot elements. + hover_name : Optional[str] + Column to appear in bold in the hover tooltip. + hover_data : Optional[List[str]] + Additional columns to display in the hover tooltip. + facet_row : Optional[str] + Column to create vertical subplots (facets). + facet_col : Optional[str] + Column to create horizontal subplots (facets). + labels : Optional[Dict[str, str]] + Dictionary to override column names for titles, legends, etc. + color_discrete_map : Optional[Dict[str, str]] + Specific color mappings for values in the `color` column. + category_orders: Optional[Dict[str, List[str]]] + Dictionary to specify the order of categorical values. + + -----Styling and Layout----- + log_x : bool + If True, the x-axis is log-scaled. + log_y : bool + If True, the y-axis is log-scaled. + range_x : Optional[List[float]] + Range for the x-axis, e.g., [0, 100]. + range_y : Optional[List[float]] + Range for the y-axis, e.g., [0, 100]. + title : str + The main title of the plot. + x_title : Optional[str] + Custom title for the x-axis. + y_title : Optional[str] + Custom title for the y-axis. + subtitle : Optional[str] + The subtitle of the plot. + template : str + Plotly template for styling (e.g., 'plotly_white'). + width : Optional[int] + Width of the plot in pixels. + height : Optional[int] + Height of the plot in pixels. + """ + + model_config = ConfigDict(extra="allow") + + # Data Mapping + x: Optional[str] = Field(None, description="Column for x-axis values.") + y: Optional[str] = Field(None, description="Column for y-axis values.") + color: Optional[str] = Field( + None, description="Column to assign color to plot elements." + ) + hover_name: Optional[str] = Field( + None, description="Column to appear in bold in the hover tooltip." + ) + hover_data: List[str] = Field( + [], description="Additional columns for the hover tooltip." + ) + facet_row: Optional[str] = Field( + None, description="Column to create vertical subplots (facets)." + ) + facet_col: Optional[str] = Field( + None, description="Column to create horizontal subplots (facets)." + ) + labels: Optional[Dict[str, str]] = Field( + None, + description="Dictionary to override column names for titles, legends, etc.", + ) + color_discrete_map: Optional[Dict[str, str]] = Field( + None, description="Specific color mappings for values in the `color` column." + ) + category_orders: Optional[Dict[str, List[str]]] = Field( + None, description="Dictionary to specify the order of categorical values." + ) + + # Styling and Layout + log_x: bool = Field(False, description="If True, use a logarithmic x-axis.") + log_y: bool = Field(False, description="If True, use a logarithmic y-axis.") + range_x: Optional[List[float]] = Field( + None, description="Range for the x-axis, e.g., [0, 100]." + ) + range_y: Optional[List[float]] = Field( + None, description="Range for the y-axis, e.g., [0, 100]." + ) + title: str = Field("Plotly Plot", description="The main title of the plot.") + x_title: Optional[str] = Field(None, description="Custom title for the x-axis.") + y_title: Optional[str] = Field(None, description="Custom title for the y-axis.") + subtitle: Optional[str] = Field(None, description="The subtitle of the plot.") + template: str = Field("plotly_white", description="Plotly template for styling.") + width: Optional[int] = Field(800, description="Width of the plot in pixels.") + height: Optional[int] = Field(600, description="Height of the plot in pixels.") + + @model_validator(mode="after") + def validate_x_or_y_provided(self) -> "PlotlyBaseConfig": + """Ensure at least one of x or y is provided for the plot.""" + if self.x is None and self.y is None: + raise ValueError( + "At least one of 'x' or 'y' must be provided for the plot." + ) + return self From 03d45c380df9e12113bbb6cb17447d2c727b8749 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 25 Aug 2025 16:26:42 +0200 Subject: [PATCH 02/32] =?UTF-8?q?=F0=9F=8E=A8=20Format(vuecore/schemas/bas?= =?UTF-8?q?ic/bar.py):=20Update=20bar=20pydantic=20model,=20extending=20fr?= =?UTF-8?q?om=20PlotlyBaseConfig=20to=20reduce=20code=20repetition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/schemas/basic/bar.py | 89 +++----------------------------- 1 file changed, 8 insertions(+), 81 deletions(-) diff --git a/src/vuecore/schemas/basic/bar.py b/src/vuecore/schemas/basic/bar.py index 52f9b57..4fbb6b1 100644 --- a/src/vuecore/schemas/basic/bar.py +++ b/src/vuecore/schemas/basic/bar.py @@ -1,10 +1,12 @@ -from typing import Dict, List, Optional -from pydantic import BaseModel, Field, ConfigDict +from typing import Dict, Optional +from pydantic import Field, ConfigDict +from vuecore.schemas.plotly_base import PlotlyBaseConfig -class BarConfig(BaseModel): +class BarConfig(PlotlyBaseConfig): """ - Pydantic model for validating and managing bar plot configurations. + Pydantic model for validating and managing bar plot configurations, + which extends the common PlotlyBaseConfig. This model serves as a curated API for the most relevant parameters for bar plots, closely aligned with the `plotly.express.bar` API @@ -20,63 +22,24 @@ class BarConfig(BaseModel): Attributes ---------- -----Data Mapping----- - x : str - Column for the x-axis values. - y : str - Column for the y-axis values. - color : Optional[str] - Column to assign color to bars. pattern_shape : Optional[str] Column to assign pattern shapes to bars. - hover_name : Optional[str] - Column to appear in bold in the hover tooltip. - hover_data : Optional[List[str]] - Additional columns to display in the hover tooltip. text : Optional[str] Column for adding text labels to bars. - facet_row : Optional[str] - Column to create vertical subplots (facets). - facet_col : Optional[str] - Column to create horizontal subplots (facets). error_x : Optional[str] Column for sizing x-axis error bars. error_y : Optional[str] Column for sizing y-axis error bars. - labels : Optional[Dict[str, str]] - Dictionary to override column names for titles, legends, etc. - color_discrete_map : Optional[Dict[str, str]] - Specific color mappings for values in the `color` column. pattern_shape_map : Optional[Dict[str, str]] Specific pattern shape mappings for values in the `pattern_shape` column. + -----Styling and Layout----- opacity : float - Marker opacity (0-1). + Overall opacity of markers (0-1). orientation: str Orientation of the bars ('v' for vertical, 'h' for horizontal). barmode : str Mode for grouping bars ('group', 'overlay', 'relative'). - log_x : bool - If True, the x-axis is log-scaled. - log_y : bool - If True, the y-axis is log-scaled. - range_x : Optional[List[float]] - Range for the x-axis, e.g., [0, 100]. - range_y : Optional[List[float]] - Range for the y-axis, e.g., [0, 100]. - title : str - The main title of the plot. - x_title : Optional[str] - Custom title for the x-axis. - y_title : Optional[str] - Custom title for the y-axis. - subtitle : str - The subtitle of the plot. - template : str - Plotly template for styling (e.g., 'plotly_white'). - width : int - Width of the plot in pixels. - height : int - Height of the plot in pixels. """ # General Configuration @@ -84,33 +47,12 @@ class BarConfig(BaseModel): model_config = ConfigDict(extra="allow") # Data Mapping - x: str = Field(..., description="Column for x-axis values.") - y: str = Field(..., description="Column for y-axis values.") - color: Optional[str] = Field(None, description="Column to assign color to bars.") pattern_shape: Optional[str] = Field( None, description="Column to assign pattern shapes to bars." ) - hover_name: Optional[str] = Field( - None, description="Column for bold text in hover tooltip." - ) - hover_data: List[str] = Field( - [], description="Additional columns for the hover tooltip." - ) text: Optional[str] = Field(None, description="Column for text labels on bars.") - facet_row: Optional[str] = Field( - None, description="Column to create vertical subplots." - ) - facet_col: Optional[str] = Field( - None, description="Column to create horizontal subplots." - ) error_x: Optional[str] = Field(None, description="Column for x-axis error bars.") error_y: Optional[str] = Field(None, description="Column for y-axis error bars.") - labels: Optional[Dict[str, str]] = Field( - None, description="Override column names in the plot." - ) - color_discrete_map: Optional[Dict[str, str]] = Field( - None, description="Map values to specific colors." - ) pattern_shape_map: Optional[Dict[str, str]] = Field( None, description="Map values to specific pattern shapes." ) @@ -122,18 +64,3 @@ class BarConfig(BaseModel): description="Orientation of the bars ('v' for vertical, 'h' for horizontal).", ) barmode: str = Field("relative", description="Mode for grouping bars.") - log_x: bool = Field(False, description="If True, use a logarithmic x-axis.") - log_y: bool = Field(False, description="If True, use a logarithmic y-axis.") - range_x: Optional[List[float]] = Field( - None, description="Range for the x-axis, e.g., [0, 100]." - ) - range_y: Optional[List[float]] = Field( - None, description="Range for the y-axis, e.g., [0, 100]." - ) - title: str = Field("Bar Plot", description="The main title of the plot.") - x_title: Optional[str] = Field(None, description="Custom title for the x-axis.") - y_title: Optional[str] = Field(None, description="Custom title for the y-axis.") - subtitle: Optional[str] = Field(None, description="The subtitle for the plot.") - template: str = Field("plotly_white", description="Plotly template for styling.") - width: int = Field(800, description="Width of the plot in pixels.") - height: int = Field(600, description="Height of the plot in pixels.") From b6d632c59815779bd3682481584bdb985b083d8b Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 25 Aug 2025 16:32:09 +0200 Subject: [PATCH 03/32] =?UTF-8?q?=F0=9F=8E=A8=20Format(vuecore/schemas/bas?= =?UTF-8?q?ic/box.py):=20Update=20box=20pydantic=20model,=20extending=20fr?= =?UTF-8?q?om=20PlotlyBaseConfig=20to=20reduce=20code=20repetition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/schemas/basic/bar.py | 2 +- src/vuecore/schemas/basic/box.py | 96 +++----------------------------- 2 files changed, 8 insertions(+), 90 deletions(-) diff --git a/src/vuecore/schemas/basic/bar.py b/src/vuecore/schemas/basic/bar.py index 4fbb6b1..0b09d75 100644 --- a/src/vuecore/schemas/basic/bar.py +++ b/src/vuecore/schemas/basic/bar.py @@ -6,7 +6,7 @@ class BarConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing bar plot configurations, - which extends the common PlotlyBaseConfig. + which extends PlotlyBaseConfig. This model serves as a curated API for the most relevant parameters for bar plots, closely aligned with the `plotly.express.bar` API diff --git a/src/vuecore/schemas/basic/box.py b/src/vuecore/schemas/basic/box.py index 50f9d4e..7729827 100644 --- a/src/vuecore/schemas/basic/box.py +++ b/src/vuecore/schemas/basic/box.py @@ -1,10 +1,12 @@ -from typing import Dict, List, Optional -from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from pydantic import Field, ConfigDict +from vuecore.schemas.plotly_base import PlotlyBaseConfig -class BoxConfig(BaseModel): +class BoxConfig(PlotlyBaseConfig): """ - Pydantic model for validating and managing box plot configurations. + Pydantic model for validating and managing box plot configurations, + which extends PlotlyBaseConfig. This model serves as a curated API for the most relevant parameters for box plots, closely aligned with the `plotly.express.box` API @@ -18,113 +20,29 @@ class BoxConfig(BaseModel): Attributes ---------- - -----Data Mapping----- - x : Optional[str] - Column for the x-axis values. - y : Optional[str] - Column for the y-axis values. - color : Optional[str] - Column to assign color to box plots. - hover_name : Optional[str] - Column to appear in bold in the hover tooltip. - hover_data : List[str] - Additional columns to display in the hover tooltip. - facet_row : Optional[str] - Column to create vertical subplots (facets). - facet_col : Optional[str] - Column to create horizontal subplots (facets). - labels : Optional[Dict[str, str]] - Dictionary to override column names for titles, legends, etc. - color_discrete_map : Optional[Dict[str, str]] - Specific color mappings for values in the `color` column. - category_orders : Optional[Dict[str, List[str]]] - Dictionary to specify the order of categorical values. -----Styling and Layout----- - orientation: str + orientation: Optional[str] Orientation of the box plots ('v' for vertical, 'h' for horizontal). boxmode : str Mode for grouping boxes ('group' or 'overlay'). - log_x : bool - If True, the x-axis is log-scaled. - log_y : bool - If True, the y-axis is log-scaled. - range_x : Optional[List[float]] - Range for the x-axis, e.g., [0, 100]. - range_y : Optional[List[float]] - Range for the y-axis, e.g., [0, 100]. notched : bool If True, boxes are drawn with notches. points : str Method to display sample points ('outliers', 'all', 'suspectedoutliers', False). - title : str - The main title of the plot. - x_title : Optional[str] - Custom title for the x-axis. - y_title : Optional[str] - Custom title for the y-axis. - subtitle : Optional[str] - The subtitle of the plot. - template : str - Plotly template for styling (e.g., 'plotly_white'). - width : int - Width of the plot in pixels. - height : int - Height of the plot in pixels. """ # General Configuration # Allow extra parameters to pass through to Plotly model_config = ConfigDict(extra="allow") - # Data Mapping - x: Optional[str] = Field(None, description="Column for x-axis values.") - y: Optional[str] = Field(None, description="Column for y-axis values.") - color: Optional[str] = Field(None, description="Column to assign color to boxes.") - hover_name: Optional[str] = Field( - None, description="Column for bold text in hover tooltip." - ) - hover_data: List[str] = Field( - [], description="Additional columns for the hover tooltip." - ) - facet_row: Optional[str] = Field( - None, description="Column to create vertical subplots." - ) - facet_col: Optional[str] = Field( - None, description="Column to create horizontal subplots." - ) - labels: Optional[Dict[str, str]] = Field( - None, description="Override column names in the plot." - ) - color_discrete_map: Optional[Dict[str, str]] = Field( - None, description="Map values to specific colors." - ) - category_orders: Optional[Dict[str, List[str]]] = Field( - None, description="Dictionary to specify the order of categorical values." - ) - # Styling and Layout orientation: Optional[str] = Field( None, description="Orientation of the box plots ('v' for vertical, 'h' for horizontal).", ) boxmode: str = Field("group", description="Mode for grouping boxes.") - log_x: bool = Field(False, description="If True, use a logarithmic x-axis.") - log_y: bool = Field(False, description="If True, use a logarithmic y-axis.") - range_x: Optional[List[float]] = Field( - None, description="Range for the x-axis, e.g., [0, 100]." - ) - range_y: Optional[List[float]] = Field( - None, description="Range for the y-axis, e.g., [0, 100]." - ) notched: bool = Field(False, description="If True, boxes are drawn with notches.") points: str = Field( "outliers", description="Method to display sample points ('outliers', 'all', 'suspectedoutliers', False).", ) - title: str = Field("Box Plot", description="The main title of the plot.") - x_title: Optional[str] = Field(None, description="Custom title for the x-axis.") - y_title: Optional[str] = Field(None, description="Custom title for the y-axis.") - subtitle: Optional[str] = Field(None, description="The subtitle of the plot.") - template: str = Field("plotly_white", description="Plotly template for styling.") - width: Optional[int] = Field(800, description="Width of the plot in pixels.") - height: Optional[int] = Field(600, description="Height of the plot in pixels.") From 485e70dbade83666cc79dc65c227abbc277ade42 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 25 Aug 2025 16:37:27 +0200 Subject: [PATCH 04/32] =?UTF-8?q?=F0=9F=8E=A8=20Format(vuecore/schemas/bas?= =?UTF-8?q?ic/line.py):=20Update=20line=20pydantic=20model,=20extending=20?= =?UTF-8?q?from=20PlotlyBaseConfig=20to=20reduce=20code=20repetition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/schemas/basic/line.py | 95 ++++--------------------------- 1 file changed, 11 insertions(+), 84 deletions(-) diff --git a/src/vuecore/schemas/basic/line.py b/src/vuecore/schemas/basic/line.py index 02940f6..1ac0a1c 100644 --- a/src/vuecore/schemas/basic/line.py +++ b/src/vuecore/schemas/basic/line.py @@ -1,10 +1,12 @@ -from typing import Dict, List, Optional -from pydantic import BaseModel, Field, ConfigDict +from typing import Dict, Optional +from pydantic import Field, ConfigDict +from vuecore.schemas.plotly_base import PlotlyBaseConfig -class LineConfig(BaseModel): +class LineConfig(PlotlyBaseConfig): """ - Pydantic model for validating and managing line plot configurations. + Pydantic model for validating and managing line plot configurations, + which extends PlotlyBaseConfig. This model serves as a curated API for the most relevant parameters for line plots, closely aligned with the `plotly.express.line` API @@ -20,67 +22,28 @@ class LineConfig(BaseModel): Attributes ---------- -----Data Mapping----- - x : str - Column for the x-axis values. - y : str - Column for the y-axis values. line_group : Optional[str] Column to group data into separate lines. - color : Optional[str] - Column to assign color to lines. Replaces 'group'. line_dash : Optional[str] Column to assign dash styles to lines. symbol : Optional[str] Column to assign symbols to markers. - hover_name : Optional[str] - Column to appear in bold in the hover tooltip. - hover_data : Optional[List[str]] - Additional columns to display in the hover tooltip. text : Optional[str] Column for adding text labels to markers. - facet_row : Optional[str] - Column to create vertical subplots (facets). - facet_col : Optional[str] - Column to create horizontal subplots (facets). error_x : Optional[str] Column for sizing x-axis error bars. error_y : Optional[str] Column for sizing y-axis error bars. - labels : Optional[Dict[str, str]] - Dictionary to override column names for titles, legends, etc. - color_discrete_map : Optional[Dict[str, str]] - Specific color mappings for values in the `color` column. line_dash_map : Optional[Dict[str, str]] Specific dash style mappings for values in the `line_dash` column. symbol_map : Optional[Dict[str, str]] Specific symbol mappings for values in the `symbol` column. + -----Styling and Layout----- - markers : bool - If True, markers are drawn on the lines. - log_x : bool - If True, the x-axis is log-scaled. - log_y : bool - If True, the y-axis is log-scaled. - range_x : Optional[List[float]] - Range for the x-axis, e.g., [0, 100]. - range_y : Optional[List[float]] - Range for the y-axis, e.g., [0, 100]. - line_shape : Optional[str] - Determines the line shape ('linear', 'spline', 'hv', etc.). - title : str - The main title of the plot. - x_title : Optional[str] - Custom title for the x-axis. - y_title : Optional[str] - Custom title for the y-axis. - subtitle : str - The subtitle of the plot. - template : str - Plotly template for styling (e.g., 'plotly_white'). - width : int - Width of the plot in pixels. - height : int - Height of the plot in pixels. + markers: bool + If True, displays markers on the lines. + line_shape: Optional[str] + Line shape (e.g., 'linear', 'spline'). """ # General Configuration @@ -88,39 +51,18 @@ class LineConfig(BaseModel): model_config = ConfigDict(extra="allow") # Data Mapping - x: str = Field(..., description="Column for x-axis values.") - y: str = Field(..., description="Column for y-axis values.") line_group: Optional[str] = Field( None, description="Column to group data into separate lines." ) - color: Optional[str] = Field(None, description="Column to assign color to lines.") line_dash: Optional[str] = Field( None, description="Column to assign dash styles to lines." ) symbol: Optional[str] = Field( None, description="Column to assign symbols to markers." ) - hover_name: Optional[str] = Field( - None, description="Column for bold text in hover tooltip." - ) - hover_data: List[str] = Field( - [], description="Additional columns for the hover tooltip." - ) text: Optional[str] = Field(None, description="Column for text labels on markers.") - facet_row: Optional[str] = Field( - None, description="Column to create vertical subplots." - ) - facet_col: Optional[str] = Field( - None, description="Column to create horizontal subplots." - ) error_x: Optional[str] = Field(None, description="Column for x-axis error bars.") error_y: Optional[str] = Field(None, description="Column for y-axis error bars.") - labels: Optional[Dict[str, str]] = Field( - None, description="Override column names in the plot." - ) - color_discrete_map: Optional[Dict[str, str]] = Field( - None, description="Map values to specific colors." - ) line_dash_map: Optional[Dict[str, str]] = Field( None, description="Map values to specific dash styles." ) @@ -130,21 +72,6 @@ class LineConfig(BaseModel): # Styling and Layout markers: bool = Field(False, description="If True, displays markers on the lines.") - log_x: bool = Field(False, description="If True, use a logarithmic x-axis.") - log_y: bool = Field(False, description="If True, use a logarithmic y-axis.") - range_x: Optional[List[float]] = Field( - None, description="Range for the x-axis, e.g., [0, 100]." - ) - range_y: Optional[List[float]] = Field( - None, description="Range for the y-axis, e.g., [0, 100]." - ) line_shape: Optional[str] = Field( "linear", description="Line shape (e.g., 'linear', 'spline')." ) - title: str = Field("Line Plot", description="The main title of the plot.") - x_title: Optional[str] = Field(None, description="Custom title for the x-axis.") - y_title: Optional[str] = Field(None, description="Custom title for the y-axis.") - subtitle: Optional[str] = Field(None, description="The subtitle for the plot.") - template: str = Field("plotly_white", description="Plotly template for styling.") - width: int = Field(800, description="Width of the plot in pixels.") - height: int = Field(600, description="Height of the plot in pixels.") From 5a4fb202acb5445c81708ceb7eea0ac0f379aef4 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 25 Aug 2025 16:43:45 +0200 Subject: [PATCH 05/32] =?UTF-8?q?=F0=9F=8E=A8=20Format(vuecore/schemas/bas?= =?UTF-8?q?ic/scatter.py):=20Update=20scatter=20pydantic=20model,=20extend?= =?UTF-8?q?ing=20from=20PlotlyBaseConfig=20to=20reduce=20code=20repetition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/schemas/basic/scatter.py | 112 +++++---------------------- 1 file changed, 18 insertions(+), 94 deletions(-) diff --git a/src/vuecore/schemas/basic/scatter.py b/src/vuecore/schemas/basic/scatter.py index 19d67b1..72f9d64 100644 --- a/src/vuecore/schemas/basic/scatter.py +++ b/src/vuecore/schemas/basic/scatter.py @@ -1,8 +1,9 @@ -from typing import Dict, List, Optional -from pydantic import BaseModel, Field, ConfigDict, model_validator +from typing import List, Optional +from pydantic import Field, ConfigDict, model_validator +from vuecore.schemas.plotly_base import PlotlyBaseConfig -class ScatterConfig(BaseModel): +class ScatterConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing scatter plot configurations. @@ -18,140 +19,63 @@ class ScatterConfig(BaseModel): `plotly.graph_objects.Figure` call. Attributes - --------- + ---------- -----Data Mapping----- - x : str - Column name for x-axis values. - y : str - Column name for y-axis values. - color : Optional[str] - Column to assign color to markers. symbol : Optional[str] Column to assign marker symbols. size : Optional[str] Column to determine marker size. - hover_name : Optional[str] - Column for bold text in hover tooltip. - hover_data : List[str] - Additional columns for hover tooltip. text : Optional[str] Column for text labels on markers. - facet_row : Optional[str] - Column for vertical facetting. - facet_col : Optional[str] - Column for horizontal facetting. error_x : Optional[str] Column for x-axis error bars. error_y : Optional[str] Column for y-axis error bars. - labels : Optional[Dict[str, str]] - Column name overrides for display. - color_discrete_map : Optional[Dict[str, str]] - Specific color mappings for color column values. symbol_map : Optional[Dict[str, str]] Specific symbol mappings for symbol column values. size_max : int Maximum marker size. + -----Styling and Layout----- opacity : float - Marker opacity (0-1). + Overall opacity of markers (0-1). trendline : Optional[str] Trendline type (ols/lowess/rolling/expanding/ewm). trendline_options : Optional[Dict] Advanced options for trendlines. - log_x : bool - Enable logarithmic x-axis. - log_y : bool - Enable logarithmic y-axis. - range_x : Optional[List[float]] - Manual x-axis range [min, max]. - range_y : Optional[List[float]] - Manual y-axis range [min, max]. - title : str - Main plot title. - x_title : Optional[str] - Custom title for the x-axis. - y_title : Optional[str] - Custom title for the y-axis. - subtitle : Optional[str] - Plot subtitle. - template : str - Plotly visual theme/template. - width : int - Plot width in pixels. - height : int - Plot height in pixels. - color_by_density : bool - Color points by density instead of category. - marker_line_width : float + marker_line_width: float Width of marker border lines. - marker_line_color : str + marker_line_color: str Color of marker border lines. + + -----Special features----- + color_by_density: bool + Color points by density instead of category. """ # General Configuration # Allow extra parameters to pass through to Plotly model_config = ConfigDict(extra="allow") - # Data mapping - x: str = Field(..., description="Column for x-axis values.") - y: str = Field(..., description="Column for y-axis values.") - color: Optional[str] = Field( - None, description="Column for color assignment (replaces 'group')." - ) - symbol: Optional[str] = Field( - None, description="Column for marker symbol assignment." - ) + # Data Mapping + symbol: Optional[str] = Field(None, description="Column to assign marker symbols.") size: Optional[str] = Field(None, description="Column to determine marker size.") - hover_name: Optional[str] = Field( - None, description="Column for bold text in hover tooltip." - ) - hover_data: List[str] = Field( - [], description="Additional columns for hover tooltip." - ) text: Optional[str] = Field(None, description="Column for text labels on markers.") - facet_row: Optional[str] = Field(None, description="Column for vertical facetting.") - facet_col: Optional[str] = Field( - None, description="Column for horizontal facetting." - ) error_x: Optional[str] = Field(None, description="Column for x-axis error bars.") error_y: Optional[str] = Field(None, description="Column for y-axis error bars.") - labels: Optional[Dict[str, str]] = Field( - None, description="Column name overrides for display purposes." - ) - color_discrete_map: Optional[Dict[str, str]] = Field( - None, description="Specific color mappings for color column values." - ) symbol_map: Optional[Dict[str, str]] = Field( None, description="Specific symbol mappings for symbol column values." ) size_max: int = Field(20, description="Maximum size for markers.") # Styling and Layout - opacity: float = Field(0.8, ge=0, le=1, description="Overall opacity of markers.") + opacity: float = Field(0.8, description="Overall opacity of markers.") trendline: Optional[str] = Field( None, description="Trendline type (ols/lowess/rolling/expanding/ewm)." ) trendline_options: Optional[Dict] = Field( None, description="Advanced options for trendline configuration." ) - log_x: bool = Field(False, description="Enable logarithmic x-axis scale.") - log_y: bool = Field(False, description="Enable logarithmic y-axis scale.") - range_x: Optional[List[float]] = Field( - None, description="Manual x-axis range [min, max]." - ) - range_y: Optional[List[float]] = Field( - None, description="Manual y-axis range [min, max]." - ) - title: str = Field("Scatter Plot", description="Main title of the plot.") - subtitle: Optional[str] = Field( - None, description="Subtitle displayed below main title." - ) - x_title: Optional[str] = Field(None, description="Custom title for the x-axis.") - y_title: Optional[str] = Field(None, description="Custom title for the y-axis.") - template: str = Field("plotly_white", description="Plotly visual theme/template.") - width: int = Field(800, description="Plot width in pixels.") - height: int = Field(600, description="Plot height in pixels.") marker_line_width: float = Field( 0.5, ge=0, description="Width of marker border lines." ) @@ -168,7 +92,7 @@ class ScatterConfig(BaseModel): def validate_exclusive_color_options(self) -> "ScatterConfig": if self.color_by_density and self.color: raise ValueError( - "Cannot use both 'color' and 'color_by_density'. " - "These options are mutually exclusive." + "Cannot use both 'color_by_density' and 'color' parameters. " + "Please choose only one for coloring the markers." ) return self From 2fdabf85620f2e36319d606fd2e7e92769af5591 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 25 Aug 2025 16:45:28 +0200 Subject: [PATCH 06/32] =?UTF-8?q?=E2=9E=95=20Format(vuecore/schemas/basic/?= =?UTF-8?q?scatter.py):Correct=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/schemas/basic/scatter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vuecore/schemas/basic/scatter.py b/src/vuecore/schemas/basic/scatter.py index 72f9d64..8f9429a 100644 --- a/src/vuecore/schemas/basic/scatter.py +++ b/src/vuecore/schemas/basic/scatter.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Dict, Optional from pydantic import Field, ConfigDict, model_validator from vuecore.schemas.plotly_base import PlotlyBaseConfig From e5d3862513d24c1e1884d4e6c39be52c71483614 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 11:58:56 +0200 Subject: [PATCH 07/32] =?UTF-8?q?=E2=9C=A8=20Feat(src/vuecore/utils/=5F=5F?= =?UTF-8?q?init=5F=5F.py):=20add=20combine=5Fdocstrings=20decorator=20to?= =?UTF-8?q?=20combine=20a=20class's=20docstring=20with=20its=20parent's=20?= =?UTF-8?q?docstring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/utils/__init__.py | 74 +++++++++++++++++++++++++++++++++ src/vuecore/utils/validation.py | 1 - 2 files changed, 74 insertions(+), 1 deletion(-) delete mode 100644 src/vuecore/utils/validation.py diff --git a/src/vuecore/utils/__init__.py b/src/vuecore/utils/__init__.py index e69de29..df3389b 100644 --- a/src/vuecore/utils/__init__.py +++ b/src/vuecore/utils/__init__.py @@ -0,0 +1,74 @@ +""" +This module contains utility functions for the vuecore library. +""" + +import re +from typing import Type + + +def combine_docstrings(cls: Type) -> Type: + """ + Decorator to combine a class's docstring with its parent's docstring, + specifically for Pydantic models. + + This function finds the `Attributes` section in the parent class's docstring + and prepends it to the `Attributes` section of the decorated child class. + This ensures all inherited parameters are properly documented for runtime + isnpection (e.g., using `help()` or `?`). + + Parameters + ---------- + cls : Type + The class to be decorated. + + Returns + ------- + Type + The decorated class with the combined docstring. + """ + # Retrieve the docstrings of the class and its parent + child_doc = getattr(cls, "__doc__", "") + parent_doc = getattr(cls.__base__, "__doc__", "") + + if not parent_doc or not child_doc: + return cls + + # Create a regex pattern to find the "Attributes" section and apply to + # both docstrings + pattern = re.compile(r"(\s*Attributes\n\s*-+\s*\n)", re.IGNORECASE) + parent_parts = pattern.split(parent_doc, 1) + child_parts = pattern.split(child_doc, 1) + + # Proceed only if the parent has an "Attributes" section + if len(parent_parts) < 3: + return cls + + # Extract the parent attributes section and formt it + parent_attributes = parent_parts[2].strip() + parent_block = ( + f"\nInherited parameters from {cls.__base__.__name__}\n" + f"-----------------------------\n" + f"{parent_attributes}\n" + ) + + # Define the section header for attributes + section_header = "Attributes\n----------" + + # Reconstruct the docstring + if len(child_parts) > 1: + # If the child has Attributes, inject parent block before child’s attributes + child_header = child_parts[0].strip() + child_attributes = child_parts[2].strip() + child_block = ( + f"Parameters from {cls.__name__}\n" + f"-----------------------------\n" + f"{child_attributes}\n" + ) + cls.__doc__ = ( + f"{child_header}\n\n{section_header}\n" f"{parent_block}\n{child_block}" + ) + else: + # If the child has no Attributes, just use the parent's + cls.__doc__ = f"{child_doc}\n\n{section_header}\n{parent_block}" + + return cls diff --git a/src/vuecore/utils/validation.py b/src/vuecore/utils/validation.py deleted file mode 100644 index 8b13789..0000000 --- a/src/vuecore/utils/validation.py +++ /dev/null @@ -1 +0,0 @@ - From 9f79985906ce9e445169f350a70055d493c288df Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 12:00:42 +0200 Subject: [PATCH 08/32] =?UTF-8?q?=E2=9C=A8=20Feat:=20add=20combine=5Fdocst?= =?UTF-8?q?rings=20decorator=20to=20the=20bar,=20box,=20scatter,=20and=20l?= =?UTF-8?q?ine=20plots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/schemas/basic/bar.py | 2 ++ src/vuecore/schemas/basic/box.py | 2 ++ src/vuecore/schemas/basic/line.py | 2 ++ src/vuecore/schemas/basic/scatter.py | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/vuecore/schemas/basic/bar.py b/src/vuecore/schemas/basic/bar.py index 0b09d75..4006fee 100644 --- a/src/vuecore/schemas/basic/bar.py +++ b/src/vuecore/schemas/basic/bar.py @@ -1,8 +1,10 @@ from typing import Dict, Optional from pydantic import Field, ConfigDict from vuecore.schemas.plotly_base import PlotlyBaseConfig +from vuecore.utils import combine_docstrings +@combine_docstrings class BarConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing bar plot configurations, diff --git a/src/vuecore/schemas/basic/box.py b/src/vuecore/schemas/basic/box.py index 7729827..f34ff5e 100644 --- a/src/vuecore/schemas/basic/box.py +++ b/src/vuecore/schemas/basic/box.py @@ -1,8 +1,10 @@ from typing import Optional from pydantic import Field, ConfigDict from vuecore.schemas.plotly_base import PlotlyBaseConfig +from vuecore.utils import combine_docstrings +@combine_docstrings class BoxConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing box plot configurations, diff --git a/src/vuecore/schemas/basic/line.py b/src/vuecore/schemas/basic/line.py index 1ac0a1c..0cb30ff 100644 --- a/src/vuecore/schemas/basic/line.py +++ b/src/vuecore/schemas/basic/line.py @@ -1,8 +1,10 @@ from typing import Dict, Optional from pydantic import Field, ConfigDict from vuecore.schemas.plotly_base import PlotlyBaseConfig +from vuecore.utils import combine_docstrings +@combine_docstrings class LineConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing line plot configurations, diff --git a/src/vuecore/schemas/basic/scatter.py b/src/vuecore/schemas/basic/scatter.py index 8f9429a..e0cafc7 100644 --- a/src/vuecore/schemas/basic/scatter.py +++ b/src/vuecore/schemas/basic/scatter.py @@ -1,8 +1,10 @@ from typing import Dict, Optional from pydantic import Field, ConfigDict, model_validator from vuecore.schemas.plotly_base import PlotlyBaseConfig +from vuecore.utils import combine_docstrings +@combine_docstrings class ScatterConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing scatter plot configurations. From b5d5f84d5caf725e350e7510755489cf796f279a Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 12:20:14 +0200 Subject: [PATCH 09/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(src/vuecore/utils/=5F?= =?UTF-8?q?=5Finit=5F=5F.py):=20use=20dedent=20on=20parent=20and=20child?= =?UTF-8?q?=20attributes=20to=20ensure=20correct=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/utils/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vuecore/utils/__init__.py b/src/vuecore/utils/__init__.py index df3389b..712d917 100644 --- a/src/vuecore/utils/__init__.py +++ b/src/vuecore/utils/__init__.py @@ -3,6 +3,7 @@ """ import re +import textwrap from typing import Type @@ -44,7 +45,7 @@ def combine_docstrings(cls: Type) -> Type: return cls # Extract the parent attributes section and formt it - parent_attributes = parent_parts[2].strip() + parent_attributes = textwrap.dedent(parent_parts[2]).strip() parent_block = ( f"\nInherited parameters from {cls.__base__.__name__}\n" f"-----------------------------\n" @@ -58,7 +59,7 @@ def combine_docstrings(cls: Type) -> Type: if len(child_parts) > 1: # If the child has Attributes, inject parent block before child’s attributes child_header = child_parts[0].strip() - child_attributes = child_parts[2].strip() + child_attributes = textwrap.dedent(child_parts[2]).strip() child_block = ( f"Parameters from {cls.__name__}\n" f"-----------------------------\n" From 6b308e854559b306b2c5a3d7a831029f21bc1882 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 16:50:44 +0200 Subject: [PATCH 10/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(docs/conf.py):=20add?= =?UTF-8?q?=20autodoc=20configiration=20to=20avoid=20duplicate=20Pydantic?= =?UTF-8?q?=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index f514a49..7cb73da 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -93,6 +93,19 @@ "numpy": ("https://numpy.org/doc/stable/", None), } +# --- Autodoc configuration to avoid duplicate Pydantic fields --- +autoclass_content = "class" + +autodoc_default_options = { + "members": True, + "undoc-members": True, + "inherited-members": False, + "show-inheritance": False, + "exclude-members": "__weakref__, __dict__, __annotations__, model_config", +} + +autodoc_typehints = "description" + # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for From ac3c391abf6e23eae59b099405178c90531d5bbc Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 17:00:42 +0200 Subject: [PATCH 11/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(docs/conf.py):=20set?= =?UTF-8?q?=20autodoc=5Ftypehints=20to=20none=20and=20avoid=20Napoleon?= =?UTF-8?q?=E2=80=99s=20auto-parameters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 7cb73da..e2c2e39 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -104,7 +104,9 @@ "exclude-members": "__weakref__, __dict__, __annotations__, model_config", } -autodoc_typehints = "description" +autodoc_typehints = "none" +napoleon_use_param = False +napoleon_use_rtype = False # -- Options for HTML output ------------------------------------------------- From 0590ef9a7a610678627128081c5244ec04a10d35 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 17:10:16 +0200 Subject: [PATCH 12/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(docs/conf.py):=20Set?= =?UTF-8?q?=20no-members=20and=20no-inherited-members=20from=20autodoc=5Fd?= =?UTF-8?q?efault=5Foptions=20dict=20to=20True=20to=20avoid=20duplicate=20?= =?UTF-8?q?attributes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index e2c2e39..c017671 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -102,6 +102,8 @@ "inherited-members": False, "show-inheritance": False, "exclude-members": "__weakref__, __dict__, __annotations__, model_config", + "no-members": True, + "no-inherited-members": True, } autodoc_typehints = "none" From 9b757ef8271bc2914dbd4b2099bb1eccd69c1af6 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 17:21:10 +0200 Subject: [PATCH 13/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(docs/conf.py):=20Try?= =?UTF-8?q?=20autodoc=5Fpydantic=20extension=20t=20ahndle=20pydantic=20att?= =?UTF-8?q?ributes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 21 +++++---------------- pyproject.toml | 1 + 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index c017671..48768eb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -40,6 +40,7 @@ "sphinx_new_tab_link", "myst_nb", "sphinx_copybutton", + "sphinxcontrib.autodoc_pydantic", ] # https://myst-nb.readthedocs.io/en/latest/computation/execute.html @@ -93,22 +94,10 @@ "numpy": ("https://numpy.org/doc/stable/", None), } -# --- Autodoc configuration to avoid duplicate Pydantic fields --- -autoclass_content = "class" - -autodoc_default_options = { - "members": True, - "undoc-members": True, - "inherited-members": False, - "show-inheritance": False, - "exclude-members": "__weakref__, __dict__, __annotations__, model_config", - "no-members": True, - "no-inherited-members": True, -} - -autodoc_typehints = "none" -napoleon_use_param = False -napoleon_use_rtype = False +# Set options for the autodoc_pydantic extension +autodoc_pydantic_model_show_json = True # Show collapsible JSON schema +autodoc_pydantic_model_show_field_summary = False # Hide default field summary +autodoc_pydantic_field_show_constraints = True # Show constraints for fields # -- Options for HTML output ------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 1d82aa0..c7d2bbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,7 @@ docs = [ "sphinx-new-tab-link!=0.2.2", "jupytext", "sphinx-copybutton", + "autodoc_pydantic", ] dev = [ "black", From b9374a7ae6e02fe79289bf5aabc2888f7d944cd2 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 17:37:51 +0200 Subject: [PATCH 14/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(.readthedocs.yaml):=20?= =?UTF-8?q?fix=20nltk=20build=20error=20by=20downloading=20the=20corpora?= =?UTF-8?q?=20during=20the=20RTD=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .readthedocs.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 0713d0a..bf78d2b 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -23,6 +23,9 @@ build: - libpango-1.0-0 - libcairo2 - libasound2 + jobs: + post_build: + - python -m nltk.downloader stopwords # Build documentation in the "docs/" directory with Sphinx sphinx: From bdefb0c349c702500ebb5f26e2f6366d9693876a Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 17:44:43 +0200 Subject: [PATCH 15/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(docs/conf.py):=20load?= =?UTF-8?q?=20NLTK=20stopwords=20in=20the=20conf.py=20to=20avoid=20build?= =?UTF-8?q?=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .readthedocs.yaml | 3 --- docs/conf.py | 8 ++++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index bf78d2b..0713d0a 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -23,9 +23,6 @@ build: - libpango-1.0-0 - libcairo2 - libasound2 - jobs: - post_build: - - python -m nltk.downloader stopwords # Build documentation in the "docs/" directory with Sphinx sphinx: diff --git a/docs/conf.py b/docs/conf.py index 48768eb..d72c1d1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,6 +4,14 @@ # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html +import nltk + +# Make sure stopwords are available for autodoc +try: + nltk.data.find("corpora/stopwords") +except LookupError: + nltk.download("stopwords") + # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, From af0b3da8996713bfa92a3902f89da58fcc1581b8 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 17:51:41 +0200 Subject: [PATCH 16/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(docs/conf.py):=20add?= =?UTF-8?q?=20extra=20parameters=20to=20fix=20duplicated=20attributes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index d72c1d1..2b032d2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -103,9 +103,9 @@ } # Set options for the autodoc_pydantic extension -autodoc_pydantic_model_show_json = True # Show collapsible JSON schema -autodoc_pydantic_model_show_field_summary = False # Hide default field summary -autodoc_pydantic_field_show_constraints = True # Show constraints for fields +autodoc_pydantic_model_show_config_summary = False +autodoc_pydantic_model_show_config = False +autodoc_pydantic_model_show_field_summary = False # -- Options for HTML output ------------------------------------------------- From c835b71a13411d577f7483193c312d921596c604 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 18:01:04 +0200 Subject: [PATCH 17/32] =?UTF-8?q?=E2=8F=AA=EF=B8=8F=20Revert=20changes=20o?= =?UTF-8?q?n=20conf.py=20bc=20autodoc=5Fpydantic=20did=20not=20fix=20the?= =?UTF-8?q?=20duplicated=20attributes=20problem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 15 --------------- pyproject.toml | 1 - 2 files changed, 16 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 2b032d2..40f9ea5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,14 +4,6 @@ # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html -import nltk - -# Make sure stopwords are available for autodoc -try: - nltk.data.find("corpora/stopwords") -except LookupError: - nltk.download("stopwords") - # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, @@ -48,7 +40,6 @@ "sphinx_new_tab_link", "myst_nb", "sphinx_copybutton", - "sphinxcontrib.autodoc_pydantic", ] # https://myst-nb.readthedocs.io/en/latest/computation/execute.html @@ -90,7 +81,6 @@ "conf.py", ] - # Intersphinx options intersphinx_mapping = { "python": ("https://docs.python.org/3", None), @@ -102,11 +92,6 @@ "numpy": ("https://numpy.org/doc/stable/", None), } -# Set options for the autodoc_pydantic extension -autodoc_pydantic_model_show_config_summary = False -autodoc_pydantic_model_show_config = False -autodoc_pydantic_model_show_field_summary = False - # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for diff --git a/pyproject.toml b/pyproject.toml index c7d2bbe..1d82aa0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,6 @@ docs = [ "sphinx-new-tab-link!=0.2.2", "jupytext", "sphinx-copybutton", - "autodoc_pydantic", ] dev = [ "black", From cf090e44d4763b4496e9e065511d0a14b2a801a0 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 18:13:46 +0200 Subject: [PATCH 18/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(docs/conf.py):=20add?= =?UTF-8?q?=20autodoc=5Fdefault=5Foptions=20options=20to=20avoid=20duplica?= =?UTF-8?q?ted=20attributes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index 40f9ea5..0a0b641 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -92,6 +92,17 @@ "numpy": ("https://numpy.org/doc/stable/", None), } +# Prevents autodoc from automatically adding a fields table for Pydantic models +autodoc_default_options = { + "members": True, + "undoc-members": True, + "private-members": False, + "special-members": False, + "inherited-members": False, + "show-inheritance": False, + "exclude-members": "__weakref__", +} + # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for From a031c1cb7bc56fb2c7332becc2d04f829e69677e Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Mon, 8 Sep 2025 18:30:57 +0200 Subject: [PATCH 19/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(docs/conf.py):=20Add?= =?UTF-8?q?=20event=20handler=20to=20avoid=20duplicate=20attributes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 0a0b641..14f00c9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -92,17 +92,6 @@ "numpy": ("https://numpy.org/doc/stable/", None), } -# Prevents autodoc from automatically adding a fields table for Pydantic models -autodoc_default_options = { - "members": True, - "undoc-members": True, - "private-members": False, - "special-members": False, - "inherited-members": False, - "show-inheritance": False, - "exclude-members": "__weakref__", -} - # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for @@ -178,6 +167,16 @@ def run_apidoc(_): ] ) + # Skip documenting Pydantic fields to avoid duplicate aattributes in the docs + def autodoc_skip_member(app, what, name, obj, skip, options): + # We only care about Pydantic models + if what == "class" and hasattr(obj, "model_fields"): + # Check if the member name is a Pydantic field + if name in obj.model_fields: + return True + return skip + def setup(app): app.connect("builder-inited", run_split_readme) app.connect("builder-inited", run_apidoc) + app.connect("autodoc-skip-member", autodoc_skip_member) From d5e0cdb7fc8a2f1cd8546e893277917a0f7d3e12 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Tue, 9 Sep 2025 10:58:49 +0200 Subject: [PATCH 20/32] =?UTF-8?q?=E2=8F=AA=EF=B8=8F=20Revert=20change=20of?= =?UTF-8?q?=20event=20handler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 14f00c9..bbbb532 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,8 +32,8 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.autodoc.typehints", + # "sphinx.ext.autodoc", + # "sphinx.ext.autodoc.typehints", "sphinx.ext.viewcode", "sphinx.ext.napoleon", "sphinx.ext.intersphinx", @@ -167,16 +167,6 @@ def run_apidoc(_): ] ) - # Skip documenting Pydantic fields to avoid duplicate aattributes in the docs - def autodoc_skip_member(app, what, name, obj, skip, options): - # We only care about Pydantic models - if what == "class" and hasattr(obj, "model_fields"): - # Check if the member name is a Pydantic field - if name in obj.model_fields: - return True - return skip - def setup(app): app.connect("builder-inited", run_split_readme) app.connect("builder-inited", run_apidoc) - app.connect("autodoc-skip-member", autodoc_skip_member) From 9dd85ac36bc51e88ca896badb417fdedd01533be Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Tue, 9 Sep 2025 11:13:33 +0200 Subject: [PATCH 21/32] =?UTF-8?q?=F0=9F=8E=A8=20Style:=20fix=20indentation?= =?UTF-8?q?=20issue=20with=20docstrings=20and=20remove=20extra=20dashes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 4 ++-- src/vuecore/utils/__init__.py | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index bbbb532..40f9ea5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,8 +32,8 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - # "sphinx.ext.autodoc", - # "sphinx.ext.autodoc.typehints", + "sphinx.ext.autodoc", + "sphinx.ext.autodoc.typehints", "sphinx.ext.viewcode", "sphinx.ext.napoleon", "sphinx.ext.intersphinx", diff --git a/src/vuecore/utils/__init__.py b/src/vuecore/utils/__init__.py index 712d917..8617d25 100644 --- a/src/vuecore/utils/__init__.py +++ b/src/vuecore/utils/__init__.py @@ -28,8 +28,8 @@ def combine_docstrings(cls: Type) -> Type: The decorated class with the combined docstring. """ # Retrieve the docstrings of the class and its parent - child_doc = getattr(cls, "__doc__", "") - parent_doc = getattr(cls.__base__, "__doc__", "") + child_doc = textwrap.dedent(getattr(cls, "__doc__", "")) + parent_doc = textwrap.dedent(getattr(cls.__base__, "__doc__", "")) if not parent_doc or not child_doc: return cls @@ -45,11 +45,10 @@ def combine_docstrings(cls: Type) -> Type: return cls # Extract the parent attributes section and formt it - parent_attributes = textwrap.dedent(parent_parts[2]).strip() + parent_attributes = parent_parts[2].strip() parent_block = ( f"\nInherited parameters from {cls.__base__.__name__}\n" - f"-----------------------------\n" - f"{parent_attributes}\n" + f"\n{parent_attributes}\n" ) # Define the section header for attributes @@ -59,12 +58,8 @@ def combine_docstrings(cls: Type) -> Type: if len(child_parts) > 1: # If the child has Attributes, inject parent block before child’s attributes child_header = child_parts[0].strip() - child_attributes = textwrap.dedent(child_parts[2]).strip() - child_block = ( - f"Parameters from {cls.__name__}\n" - f"-----------------------------\n" - f"{child_attributes}\n" - ) + child_attributes = child_parts[2].strip() + child_block = f"Parameters from {cls.__name__}\n" f"\n{child_attributes}\n" cls.__doc__ = ( f"{child_header}\n\n{section_header}\n" f"{parent_block}\n{child_block}" ) From cbf8f840c0d437609130dd7aa3a3f8e0a033c7f3 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Tue, 9 Sep 2025 21:20:51 +0200 Subject: [PATCH 22/32] =?UTF-8?q?=E2=8F=AA=EF=B8=8F=20Revert=20combine=5Fd?= =?UTF-8?q?ocstring=20decorator=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/schemas/basic/bar.py | 2 - src/vuecore/schemas/basic/box.py | 2 - src/vuecore/schemas/basic/line.py | 2 - src/vuecore/schemas/basic/scatter.py | 2 - src/vuecore/utils/__init__.py | 70 ---------------------------- 5 files changed, 78 deletions(-) diff --git a/src/vuecore/schemas/basic/bar.py b/src/vuecore/schemas/basic/bar.py index 4006fee..0b09d75 100644 --- a/src/vuecore/schemas/basic/bar.py +++ b/src/vuecore/schemas/basic/bar.py @@ -1,10 +1,8 @@ from typing import Dict, Optional from pydantic import Field, ConfigDict from vuecore.schemas.plotly_base import PlotlyBaseConfig -from vuecore.utils import combine_docstrings -@combine_docstrings class BarConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing bar plot configurations, diff --git a/src/vuecore/schemas/basic/box.py b/src/vuecore/schemas/basic/box.py index f34ff5e..7729827 100644 --- a/src/vuecore/schemas/basic/box.py +++ b/src/vuecore/schemas/basic/box.py @@ -1,10 +1,8 @@ from typing import Optional from pydantic import Field, ConfigDict from vuecore.schemas.plotly_base import PlotlyBaseConfig -from vuecore.utils import combine_docstrings -@combine_docstrings class BoxConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing box plot configurations, diff --git a/src/vuecore/schemas/basic/line.py b/src/vuecore/schemas/basic/line.py index 0cb30ff..1ac0a1c 100644 --- a/src/vuecore/schemas/basic/line.py +++ b/src/vuecore/schemas/basic/line.py @@ -1,10 +1,8 @@ from typing import Dict, Optional from pydantic import Field, ConfigDict from vuecore.schemas.plotly_base import PlotlyBaseConfig -from vuecore.utils import combine_docstrings -@combine_docstrings class LineConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing line plot configurations, diff --git a/src/vuecore/schemas/basic/scatter.py b/src/vuecore/schemas/basic/scatter.py index e0cafc7..8f9429a 100644 --- a/src/vuecore/schemas/basic/scatter.py +++ b/src/vuecore/schemas/basic/scatter.py @@ -1,10 +1,8 @@ from typing import Dict, Optional from pydantic import Field, ConfigDict, model_validator from vuecore.schemas.plotly_base import PlotlyBaseConfig -from vuecore.utils import combine_docstrings -@combine_docstrings class ScatterConfig(PlotlyBaseConfig): """ Pydantic model for validating and managing scatter plot configurations. diff --git a/src/vuecore/utils/__init__.py b/src/vuecore/utils/__init__.py index 8617d25..e69de29 100644 --- a/src/vuecore/utils/__init__.py +++ b/src/vuecore/utils/__init__.py @@ -1,70 +0,0 @@ -""" -This module contains utility functions for the vuecore library. -""" - -import re -import textwrap -from typing import Type - - -def combine_docstrings(cls: Type) -> Type: - """ - Decorator to combine a class's docstring with its parent's docstring, - specifically for Pydantic models. - - This function finds the `Attributes` section in the parent class's docstring - and prepends it to the `Attributes` section of the decorated child class. - This ensures all inherited parameters are properly documented for runtime - isnpection (e.g., using `help()` or `?`). - - Parameters - ---------- - cls : Type - The class to be decorated. - - Returns - ------- - Type - The decorated class with the combined docstring. - """ - # Retrieve the docstrings of the class and its parent - child_doc = textwrap.dedent(getattr(cls, "__doc__", "")) - parent_doc = textwrap.dedent(getattr(cls.__base__, "__doc__", "")) - - if not parent_doc or not child_doc: - return cls - - # Create a regex pattern to find the "Attributes" section and apply to - # both docstrings - pattern = re.compile(r"(\s*Attributes\n\s*-+\s*\n)", re.IGNORECASE) - parent_parts = pattern.split(parent_doc, 1) - child_parts = pattern.split(child_doc, 1) - - # Proceed only if the parent has an "Attributes" section - if len(parent_parts) < 3: - return cls - - # Extract the parent attributes section and formt it - parent_attributes = parent_parts[2].strip() - parent_block = ( - f"\nInherited parameters from {cls.__base__.__name__}\n" - f"\n{parent_attributes}\n" - ) - - # Define the section header for attributes - section_header = "Attributes\n----------" - - # Reconstruct the docstring - if len(child_parts) > 1: - # If the child has Attributes, inject parent block before child’s attributes - child_header = child_parts[0].strip() - child_attributes = child_parts[2].strip() - child_block = f"Parameters from {cls.__name__}\n" f"\n{child_attributes}\n" - cls.__doc__ = ( - f"{child_header}\n\n{section_header}\n" f"{parent_block}\n{child_block}" - ) - else: - # If the child has no Attributes, just use the parent's - cls.__doc__ = f"{child_doc}\n\n{section_header}\n{parent_block}" - - return cls From e9882c18c11268649b0706b66d7523a839ac744d Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Tue, 9 Sep 2025 21:23:28 +0200 Subject: [PATCH 23/32] =?UTF-8?q?=F0=9F=94=A5=20Remove=20manual=20docstrin?= =?UTF-8?q?gs=20attributes=20from=20Pydantic=20schemas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/schemas/__init__.py | 0 src/vuecore/schemas/basic/bar.py | 22 ------------- src/vuecore/schemas/basic/box.py | 12 ------- src/vuecore/schemas/basic/line.py | 26 --------------- src/vuecore/schemas/basic/scatter.py | 34 -------------------- src/vuecore/schemas/plotly_base.py | 48 ---------------------------- 6 files changed, 142 deletions(-) create mode 100644 src/vuecore/schemas/__init__.py diff --git a/src/vuecore/schemas/__init__.py b/src/vuecore/schemas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/vuecore/schemas/basic/bar.py b/src/vuecore/schemas/basic/bar.py index 0b09d75..51a2e67 100644 --- a/src/vuecore/schemas/basic/bar.py +++ b/src/vuecore/schemas/basic/bar.py @@ -18,28 +18,6 @@ class BarConfig(PlotlyBaseConfig): defined here, and also accepts additional Plotly keyword arguments, forwarding them to the appropriate `plotly.express.bar` or `plotly.graph_objects.Figure` call. - - Attributes - ---------- - -----Data Mapping----- - pattern_shape : Optional[str] - Column to assign pattern shapes to bars. - text : Optional[str] - Column for adding text labels to bars. - error_x : Optional[str] - Column for sizing x-axis error bars. - error_y : Optional[str] - Column for sizing y-axis error bars. - pattern_shape_map : Optional[Dict[str, str]] - Specific pattern shape mappings for values in the `pattern_shape` column. - - -----Styling and Layout----- - opacity : float - Overall opacity of markers (0-1). - orientation: str - Orientation of the bars ('v' for vertical, 'h' for horizontal). - barmode : str - Mode for grouping bars ('group', 'overlay', 'relative'). """ # General Configuration diff --git a/src/vuecore/schemas/basic/box.py b/src/vuecore/schemas/basic/box.py index 7729827..c8ed9c1 100644 --- a/src/vuecore/schemas/basic/box.py +++ b/src/vuecore/schemas/basic/box.py @@ -17,18 +17,6 @@ class BoxConfig(PlotlyBaseConfig): structure. The plotting function handles parameters defined here, and also accepts additional Plotly keyword arguments, forwarding them to the appropriate `plotly.express.box` or `plotly.graph_objects.Figure` call. - - Attributes - ---------- - -----Styling and Layout----- - orientation: Optional[str] - Orientation of the box plots ('v' for vertical, 'h' for horizontal). - boxmode : str - Mode for grouping boxes ('group' or 'overlay'). - notched : bool - If True, boxes are drawn with notches. - points : str - Method to display sample points ('outliers', 'all', 'suspectedoutliers', False). """ # General Configuration diff --git a/src/vuecore/schemas/basic/line.py b/src/vuecore/schemas/basic/line.py index 1ac0a1c..ff20b65 100644 --- a/src/vuecore/schemas/basic/line.py +++ b/src/vuecore/schemas/basic/line.py @@ -18,32 +18,6 @@ class LineConfig(PlotlyBaseConfig): defined here, and also accepts additional Plotly keyword arguments, forwarding them to the appropriate `plotly.express.line` or `plotly.graph_objects.Figure` call. - - Attributes - ---------- - -----Data Mapping----- - line_group : Optional[str] - Column to group data into separate lines. - line_dash : Optional[str] - Column to assign dash styles to lines. - symbol : Optional[str] - Column to assign symbols to markers. - text : Optional[str] - Column for adding text labels to markers. - error_x : Optional[str] - Column for sizing x-axis error bars. - error_y : Optional[str] - Column for sizing y-axis error bars. - line_dash_map : Optional[Dict[str, str]] - Specific dash style mappings for values in the `line_dash` column. - symbol_map : Optional[Dict[str, str]] - Specific symbol mappings for values in the `symbol` column. - - -----Styling and Layout----- - markers: bool - If True, displays markers on the lines. - line_shape: Optional[str] - Line shape (e.g., 'linear', 'spline'). """ # General Configuration diff --git a/src/vuecore/schemas/basic/scatter.py b/src/vuecore/schemas/basic/scatter.py index 8f9429a..deb1e56 100644 --- a/src/vuecore/schemas/basic/scatter.py +++ b/src/vuecore/schemas/basic/scatter.py @@ -17,40 +17,6 @@ class ScatterConfig(PlotlyBaseConfig): defined here, and also accepts additional Plotly keyword arguments, forwarding them to the appropriate `plotly.express.scatter` or `plotly.graph_objects.Figure` call. - - Attributes - ---------- - -----Data Mapping----- - symbol : Optional[str] - Column to assign marker symbols. - size : Optional[str] - Column to determine marker size. - text : Optional[str] - Column for text labels on markers. - error_x : Optional[str] - Column for x-axis error bars. - error_y : Optional[str] - Column for y-axis error bars. - symbol_map : Optional[Dict[str, str]] - Specific symbol mappings for symbol column values. - size_max : int - Maximum marker size. - - -----Styling and Layout----- - opacity : float - Overall opacity of markers (0-1). - trendline : Optional[str] - Trendline type (ols/lowess/rolling/expanding/ewm). - trendline_options : Optional[Dict] - Advanced options for trendlines. - marker_line_width: float - Width of marker border lines. - marker_line_color: str - Color of marker border lines. - - -----Special features----- - color_by_density: bool - Color points by density instead of category. """ # General Configuration diff --git a/src/vuecore/schemas/plotly_base.py b/src/vuecore/schemas/plotly_base.py index a8e704d..d1c7369 100644 --- a/src/vuecore/schemas/plotly_base.py +++ b/src/vuecore/schemas/plotly_base.py @@ -14,54 +14,6 @@ class PlotlyBaseConfig(BaseModel): to ensure consistency and reduce code repetition. It uses a validator to enforce that at least one of the x or y axes is provided. Plot-specific schemas should inherit from this model. - - Attributes - ---------- - -----Data Mapping----- - x : Optional[str] - Column for the x-axis values. - y : Optional[str] - Column for the y-axis values. - color : Optional[str] - Column to assign color to plot elements. - hover_name : Optional[str] - Column to appear in bold in the hover tooltip. - hover_data : Optional[List[str]] - Additional columns to display in the hover tooltip. - facet_row : Optional[str] - Column to create vertical subplots (facets). - facet_col : Optional[str] - Column to create horizontal subplots (facets). - labels : Optional[Dict[str, str]] - Dictionary to override column names for titles, legends, etc. - color_discrete_map : Optional[Dict[str, str]] - Specific color mappings for values in the `color` column. - category_orders: Optional[Dict[str, List[str]]] - Dictionary to specify the order of categorical values. - - -----Styling and Layout----- - log_x : bool - If True, the x-axis is log-scaled. - log_y : bool - If True, the y-axis is log-scaled. - range_x : Optional[List[float]] - Range for the x-axis, e.g., [0, 100]. - range_y : Optional[List[float]] - Range for the y-axis, e.g., [0, 100]. - title : str - The main title of the plot. - x_title : Optional[str] - Custom title for the x-axis. - y_title : Optional[str] - Custom title for the y-axis. - subtitle : Optional[str] - The subtitle of the plot. - template : str - Plotly template for styling (e.g., 'plotly_white'). - width : Optional[int] - Width of the plot in pixels. - height : Optional[int] - Height of the plot in pixels. """ model_config = ConfigDict(extra="allow") From 8991a11e9383d01c96f9be1e2631f8cd3ec0627a Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Tue, 9 Sep 2025 23:42:21 +0200 Subject: [PATCH 24/32] =?UTF-8?q?=E2=9C=A8=20Feat:=20Use=20autodoc=5Fpydan?= =?UTF-8?q?tic=20sphinx=20extension=20to=20show=20the=20pydantic=20docstri?= =?UTF-8?q?ngs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/conf.py | 34 +++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 40f9ea5..580e40c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,6 +4,14 @@ # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html +import nltk + +# Make sure stopwords are available for autodoc +try: + nltk.data.find("corpora/stopwords") +except LookupError: + nltk.download("stopwords") + # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, @@ -27,7 +35,6 @@ # -- General configuration --------------------------------------------------- - # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. @@ -40,6 +47,7 @@ "sphinx_new_tab_link", "myst_nb", "sphinx_copybutton", + "sphinxcontrib.autodoc_pydantic", ] # https://myst-nb.readthedocs.io/en/latest/computation/execute.html @@ -92,6 +100,30 @@ "numpy": ("https://numpy.org/doc/stable/", None), } +# Options for the autodoc_pydantic extension +autodoc_pydantic_field_show_default = True +autodoc_pydantic_field_show_constraints = True +autodoc_pydantic_field_list_validators = True +autodoc_pydantic_model_signature_prefix = "class" +autodoc_pydantic_field_signature_prefix = "attribute" +autodoc_pydantic_field_show_required = True +autodoc_pydantic_field_show_optional = True +autodoc_pydantic_field_show_default = True +autodoc_pydantic_field_doc_policy = "description" +autodoc_pydantic_model_member_order = "bysource" +autodoc_pydantic_model_show_json = False +autodoc_pydantic_model_show_field_summary = False +autodoc_pydantic_model_show_config_summary = False +autodoc_pydantic_model_show_validator_summary = False +autodoc_pydantic_model_hide_paramlist = False +autodoc_pydantic_field_list_validators = False + +# Options for the autodoc extension +autodoc_default_options = { + "inherited-members": "BaseModel", + "show-inheritance": True, +} + # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for diff --git a/pyproject.toml b/pyproject.toml index 1d82aa0..c7d2bbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,7 @@ docs = [ "sphinx-new-tab-link!=0.2.2", "jupytext", "sphinx-copybutton", + "autodoc_pydantic", ] dev = [ "black", From 1d4ae757dbb282feaae52729f2c0ad09355da6b7 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Tue, 9 Sep 2025 23:43:22 +0200 Subject: [PATCH 25/32] =?UTF-8?q?=F0=9F=8E=A8=20Add=20=5F=5Finit=5F=5F.py?= =?UTF-8?q?=20file=20on=20the=20src/vuecore/plots=20folder=20to=20make=20i?= =?UTF-8?q?t=20visible=20on=20the=20sphinx=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/plots/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/vuecore/plots/__init__.py diff --git a/src/vuecore/plots/__init__.py b/src/vuecore/plots/__init__.py new file mode 100644 index 0000000..e69de29 From 2535024f545271530dc5b33e94a975f5d78a6760 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Wed, 10 Sep 2025 14:48:59 +0200 Subject: [PATCH 26/32] =?UTF-8?q?=E2=9C=A8=20Feat(vuecore/utils/docs=5Futi?= =?UTF-8?q?ls.py):=20create=20document=5Fpydant=5Fparams=20decorator=20and?= =?UTF-8?q?=20helper=20functions=20to=20add=20Pydantic=20model=20parameter?= =?UTF-8?q?s=20into=20a=20docsting=20of=20a=20target=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/utils/docs_utils.py | 143 ++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/vuecore/utils/docs_utils.py diff --git a/src/vuecore/utils/docs_utils.py b/src/vuecore/utils/docs_utils.py new file mode 100644 index 0000000..ca1dbb5 --- /dev/null +++ b/src/vuecore/utils/docs_utils.py @@ -0,0 +1,143 @@ +# vuecore/utils/doc_utils.py +from typing import Type, Dict, Any, get_origin, get_args, Optional, Union +from pydantic import BaseModel, Field +from functools import wraps +import textwrap +import re + + +def get_all_model_fields(model: Type[BaseModel]) -> Dict[str, Field]: + """ + Extract all fields from a Pydantic model, including inherited ones. + + Parameters + ---------- + model : Type[BaseModel] + The Pydantic model class from which to extract fields. + + Returns + ------- + Dict[str, Any] + A dictionary with field names as keys and field information as values. + """ + fields = {} + # Iterate through the method resolution order (mro) in reverse to start from the base classes + for cls in reversed(model.__mro__): + if issubclass(cls, BaseModel) and hasattr(cls, "model_fields"): + for field_name, field in cls.model_fields.items(): + fields[field_name] = field + return fields + + +def get_type_string(annotation: Any) -> str: + """ + Helper to get a clean type string from a type annotation. + + Parameters + ---------- + annotation : Any + The type annotation to process. + + Returns + ------- + str + A simplified string representation of the type. + """ + origin = get_origin(annotation) + if origin is Union or origin is Optional: + args = get_args(annotation) + non_none_arg = next((arg for arg in args if arg is not type(None)), None) + if non_none_arg: + return get_type_string(non_none_arg) + return "Any" + elif origin is list or annotation is list: + args = get_args(annotation) + if not args: + return "list" + inner_type = ", ".join(arg.__name__ for arg in args) + return f"list of {inner_type}" + elif origin is dict or annotation is dict: + args = get_args(annotation) + if not args: + return "dict" + key_type_str = get_type_string(args[0]) + value_type_str = get_type_string(args[1]) + return f"Dict[{key_type_str}, {value_type_str}]" + return annotation.__name__ + + +def document_pydant_params(model: Type[BaseModel]): + """ + Decorator to add Pydantic model parameters to a function's docstrings. + + Parameters + ---------- + model : Type[BaseModel] + The Pydantic model class whose fields should be documented. + + Returns + ------- + function + A decorator function that modifies the docstring of the target function. + """ + + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + return func(*args, **kwargs) + + original_doc = wrapper.__doc__ or "" + lines = original_doc.splitlines() + + # Find the end of the "Parameters" section + insert_index = -1 + # Find the line that marks the end of the Parameters section + # or the beginning of a new section like Returns or Raises + for i, line in enumerate(lines): + if re.match(r"^\s*(Returns|Raises|Examples|See Also)", line): + insert_index = i + break + + # If no other section is found, assume the end of the docstring + if insert_index == -1: + insert_index = len(lines) + + # Generate the new, detailed parameter list in NumPydocs style + fields = get_all_model_fields(model) + params_doc_lines = [] + for field_name, field in fields.items(): + type_str = get_type_string(field.annotation) + description = field.description or "No description available." + default_value = field.get_default(call_default_factory=True) + default_str = ( + f" (default: ``{default_value}``)" + if default_value is not None and default_value is not ... + else "" + ) + + # Format as a single line for the NumPy-style bulleted list + params_doc_lines.append( + f"* **{field_name}** ({type_str}) – {description}{default_str}" + ) + + # Indent all lines in the parameter list correctly + indented_params_lines = textwrap.indent( + "\n".join(params_doc_lines), prefix=" " + ).splitlines() + + # Create the kwargs documentation as a list of lines + new_kwargs_lines = [ + " **kwargs", + f" Keyword arguments for plot configuration. These arguments are validated against the ``{model.__name__}`` Pydantic model." + f" The following parameters are supported:\n", + ] + + # Add all parameter lines + new_kwargs_lines.extend(indented_params_lines) + + # Reconstruct the docstring by inserting the new lines + new_doc_lines = lines[:insert_index] + new_kwargs_lines + lines[insert_index:] + wrapper.__doc__ = "\n".join(new_doc_lines) + return wrapper + + return decorator From 8b834128b2f98d7c124407ec4c4c199e7727943e Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Wed, 10 Sep 2025 14:49:39 +0200 Subject: [PATCH 27/32] =?UTF-8?q?=E2=9C=A8=20Feat:=20add=20the=20document?= =?UTF-8?q?=5Fpydant=5Fparams=20decorator=20in=20all=20plot=20scripts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/plots/basic/bar.py | 7 ++----- src/vuecore/plots/basic/box.py | 7 ++----- src/vuecore/plots/basic/line.py | 6 ++---- src/vuecore/plots/basic/scatter.py | 6 ++---- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/vuecore/plots/basic/bar.py b/src/vuecore/plots/basic/bar.py index 1295cca..7f25d2d 100644 --- a/src/vuecore/plots/basic/bar.py +++ b/src/vuecore/plots/basic/bar.py @@ -5,8 +5,10 @@ from vuecore import EngineType from vuecore.engines import get_builder, get_saver from vuecore.schemas.basic.bar import BarConfig +from vuecore.utils.docs_utils import document_pydant_params +@document_pydant_params(BarConfig) def create_bar_plot( data: pd.DataFrame, engine: EngineType = EngineType.PLOTLY, @@ -34,11 +36,6 @@ def create_bar_plot( The file format is automatically inferred from the file extension (e.g., '.html', '.png', '.jpeg', '.svg'). Defaults to None, meaning the plot will not be saved. - **kwargs - Keyword arguments for plot configuration. These arguments are - validated against the `BarConfig` Pydantic model. Refer to - `vuecore.schemas.basic.bar.BarConfig` for all available - options and their descriptions. Returns ------- diff --git a/src/vuecore/plots/basic/box.py b/src/vuecore/plots/basic/box.py index f2e0359..6f3432b 100644 --- a/src/vuecore/plots/basic/box.py +++ b/src/vuecore/plots/basic/box.py @@ -5,8 +5,10 @@ from vuecore import EngineType from vuecore.engines import get_builder, get_saver from vuecore.schemas.basic.box import BoxConfig +from vuecore.utils.docs_utils import document_pydant_params +@document_pydant_params(BoxConfig) def create_box_plot( data: pd.DataFrame, engine: EngineType = EngineType.PLOTLY, @@ -34,11 +36,6 @@ def create_box_plot( The file format is automatically inferred from the file extension (e.g., '.html', '.png', '.jpeg', '.svg'). Defaults to None, meaning the plot will not be saved. - **kwargs - Keyword arguments for plot configuration. These arguments are - validated against the `BoxConfig` Pydantic model. Refer to - `vuecore.schemas.basic.box.BoxConfig` for all available - options and their descriptions. Returns ------- diff --git a/src/vuecore/plots/basic/line.py b/src/vuecore/plots/basic/line.py index 0324ce2..1a87b46 100644 --- a/src/vuecore/plots/basic/line.py +++ b/src/vuecore/plots/basic/line.py @@ -5,8 +5,10 @@ from vuecore import EngineType from vuecore.engines import get_builder, get_saver from vuecore.schemas.basic.line import LineConfig +from vuecore.utils.docs_utils import document_pydant_params +@document_pydant_params(LineConfig) def create_line_plot( data: pd.DataFrame, engine: EngineType = EngineType.PLOTLY, @@ -34,10 +36,6 @@ def create_line_plot( The file format is automatically inferred from the file extension (e.g., '.html', '.png', '.jpeg', '.svg'). Defaults to None, meaning the plot will not be saved. - **kwargs - Keyword arguments for plot configuration. These arguments are validated - against the `LineConfig` Pydantic model. See - `vuecore.schemas.basic.line.LineConfig` for all available options. Returns ------- diff --git a/src/vuecore/plots/basic/scatter.py b/src/vuecore/plots/basic/scatter.py index 2a05cab..58e846d 100644 --- a/src/vuecore/plots/basic/scatter.py +++ b/src/vuecore/plots/basic/scatter.py @@ -5,8 +5,10 @@ from vuecore import EngineType from vuecore.engines import get_builder, get_saver from vuecore.schemas.basic.scatter import ScatterConfig +from vuecore.utils.docs_utils import document_pydant_params +@document_pydant_params(ScatterConfig) def create_scatter_plot( data: pd.DataFrame, engine: EngineType = EngineType.PLOTLY, @@ -34,10 +36,6 @@ def create_scatter_plot( The file format is automatically inferred from the file extension (e.g., '.html', '.png', '.jpeg', '.svg'). Defaults to None, meaning the plot will not be saved. - **kwargs - Keyword arguments for plot configuration. These arguments are validated - against the `ScatterConfig` Pydantic model. See - `schemas.basic.scatter.ScatterConfig` for all available options. Returns ------- From e955a77fefe795d9e3f8d9d39116c9d4f319e8a2 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Wed, 10 Sep 2025 15:16:07 +0200 Subject: [PATCH 28/32] =?UTF-8?q?=F0=9F=8E=A8=20Format(vuecore/utils/docs?= =?UTF-8?q?=5Futils.py):=20add=20new=20line=20in=20description=20of=20docu?= =?UTF-8?q?ment=5Fpydant=5Fparams=20decorator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/utils/docs_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vuecore/utils/docs_utils.py b/src/vuecore/utils/docs_utils.py index ca1dbb5..5676d0d 100644 --- a/src/vuecore/utils/docs_utils.py +++ b/src/vuecore/utils/docs_utils.py @@ -128,7 +128,7 @@ def wrapper(*args, **kwargs): # Create the kwargs documentation as a list of lines new_kwargs_lines = [ " **kwargs", - f" Keyword arguments for plot configuration. These arguments are validated against the ``{model.__name__}`` Pydantic model." + f" Keyword arguments for plot configuration. These arguments are validated against the ``{model.__name__}`` Pydantic model.\n" f" The following parameters are supported:\n", ] From 4fedeed84520476a7a4a95102f563fafaea1ea53 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Wed, 10 Sep 2025 16:30:35 +0200 Subject: [PATCH 29/32] =?UTF-8?q?=E2=9C=85=20Feat(tests/test=5Fdocs=5Futil?= =?UTF-8?q?s.py):=20add=20tests=20for=20the=20docs=5Futils=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/utils/docs_utils.py | 3 +- tests/test_docs_utils.py | 111 ++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 tests/test_docs_utils.py diff --git a/src/vuecore/utils/docs_utils.py b/src/vuecore/utils/docs_utils.py index 5676d0d..51532bd 100644 --- a/src/vuecore/utils/docs_utils.py +++ b/src/vuecore/utils/docs_utils.py @@ -128,7 +128,8 @@ def wrapper(*args, **kwargs): # Create the kwargs documentation as a list of lines new_kwargs_lines = [ " **kwargs", - f" Keyword arguments for plot configuration. These arguments are validated against the ``{model.__name__}`` Pydantic model.\n" + f" Keyword arguments for plot configuration. These arguments are validated against", + f" the ``{model.__name__}`` Pydantic model and the engine specific parameters.\n", f" The following parameters are supported:\n", ] diff --git a/tests/test_docs_utils.py b/tests/test_docs_utils.py new file mode 100644 index 0000000..ea876dc --- /dev/null +++ b/tests/test_docs_utils.py @@ -0,0 +1,111 @@ +import pytest +import textwrap +from pydantic import BaseModel, Field +from typing import Optional, List, Dict + +# Import the decorator and helper functions from your module +from vuecore.utils.docs_utils import ( + document_pydant_params, + get_type_string, + get_all_model_fields, +) + + +# --- Test Model and Function --- +# Pydantic model with different field types for validation +class TestModel(BaseModel): + """A test model for decorator documentation.""" + + param_str: str = Field(..., description="A string parameter.") + param_int: int = Field(5, description="An integer parameter with a default.") + param_list: Optional[List[str]] = Field( + None, description="An optional list of strings." + ) + param_dict: Dict = Field({}, description="A generic dictionary parameter.") + param_bare_list: list = Field([], description="A bare list parameter.") + + +# Function to apply the decorator to and check its docstring +@document_pydant_params(TestModel) +def dummy_plot_function(data: dict): + """ + This is the original docstring. + + Parameters + ---------- + data : dict + A dictionary of sample data. + + Returns + ------- + None + Does not return anything. + """ + pass + + +# --- Tests for Helper Functions --- +def test_get_all_model_fields(): + """Verify that all fields, including inherited ones, are correctly extracted.""" + fields = get_all_model_fields(TestModel) + assert "param_str" in fields + assert "param_int" in fields + assert "param_list" in fields + assert "param_dict" in fields + assert "param_bare_list" in fields + assert len(fields) == 5 + + +@pytest.mark.parametrize( + "annotation, expected_string", + [ + (str, "str"), + (int, "int"), + (Optional[str], "str"), + (List[str], "list of str"), + (Dict, "dict"), + (list, "list"), + (Dict[str, int], "Dict[str, int]"), + ], +) +def test_get_type_string(annotation, expected_string): + """Test that the type string is correctly formatted for various types.""" + assert get_type_string(annotation) == expected_string + + +# --- Test for the Decorator --- +def test_decorator_modifies_docstring(): + """Verify the decorator correctly adds model parameters to the docstring.""" + # Define the expected docstring + expected_docstring = """ + This is the original docstring. + + Parameters + ---------- + data : dict + A dictionary of sample data. + + **kwargs + Keyword arguments for plot configuration. These arguments are validated against + the ``TestModel`` Pydantic model and the engine specific parameters. + + The following parameters are supported: + + * **param_str** (str) – A string parameter. (default: ``PydanticUndefined``) + * **param_int** (int) – An integer parameter with a default. (default: ``5``) + * **param_list** (list of str) – An optional list of strings. + * **param_dict** (dict) – A generic dictionary parameter. (default: ``{}``) + * **param_bare_list** (list) – A bare list parameter. (default: ``[]``) + Returns + ------- + None + Does not return anything. + """ + # Dedent the expected docstring for accurate comparison + expected_docstring = textwrap.dedent(expected_docstring).strip() + + # Get the decorated function's docstring and dedent it before comparison + decorated_docstring = textwrap.dedent(dummy_plot_function.__doc__).strip() + + # Assert that the docstrings are a perfect match + assert decorated_docstring == expected_docstring From 295b3164781628bc623e5416cd4b864f9f2ea3d8 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Wed, 10 Sep 2025 16:33:26 +0200 Subject: [PATCH 30/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(src/vuecore/utils/docs?= =?UTF-8?q?=5Futils.py):=20remove=20f=20on=20list=20of=20strings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/utils/docs_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vuecore/utils/docs_utils.py b/src/vuecore/utils/docs_utils.py index 51532bd..6c1abc5 100644 --- a/src/vuecore/utils/docs_utils.py +++ b/src/vuecore/utils/docs_utils.py @@ -128,7 +128,7 @@ def wrapper(*args, **kwargs): # Create the kwargs documentation as a list of lines new_kwargs_lines = [ " **kwargs", - f" Keyword arguments for plot configuration. These arguments are validated against", + " Keyword arguments for plot configuration. These arguments are validated against", f" the ``{model.__name__}`` Pydantic model and the engine specific parameters.\n", f" The following parameters are supported:\n", ] From ffc683f4704fd9d6da18bd58915298e7d5e0a68e Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Wed, 10 Sep 2025 16:48:16 +0200 Subject: [PATCH 31/32] =?UTF-8?q?=E2=9C=85=20Feat:=20update=20main=20test?= =?UTF-8?q?=20in=20the=20tests/test=5Fdocs=5Futils.py=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/utils/docs_utils.py | 2 +- tests/test_docs_utils.py | 65 +++++++++++++++++---------------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/vuecore/utils/docs_utils.py b/src/vuecore/utils/docs_utils.py index 6c1abc5..c056430 100644 --- a/src/vuecore/utils/docs_utils.py +++ b/src/vuecore/utils/docs_utils.py @@ -128,7 +128,7 @@ def wrapper(*args, **kwargs): # Create the kwargs documentation as a list of lines new_kwargs_lines = [ " **kwargs", - " Keyword arguments for plot configuration. These arguments are validated against", + " Keyword arguments for plot configuration. These arguments are validated against", f" the ``{model.__name__}`` Pydantic model and the engine specific parameters.\n", f" The following parameters are supported:\n", ] diff --git a/tests/test_docs_utils.py b/tests/test_docs_utils.py index ea876dc..4de8ad1 100644 --- a/tests/test_docs_utils.py +++ b/tests/test_docs_utils.py @@ -76,36 +76,37 @@ def test_get_type_string(annotation, expected_string): # --- Test for the Decorator --- def test_decorator_modifies_docstring(): """Verify the decorator correctly adds model parameters to the docstring.""" - # Define the expected docstring - expected_docstring = """ - This is the original docstring. - - Parameters - ---------- - data : dict - A dictionary of sample data. - - **kwargs - Keyword arguments for plot configuration. These arguments are validated against - the ``TestModel`` Pydantic model and the engine specific parameters. - - The following parameters are supported: - - * **param_str** (str) – A string parameter. (default: ``PydanticUndefined``) - * **param_int** (int) – An integer parameter with a default. (default: ``5``) - * **param_list** (list of str) – An optional list of strings. - * **param_dict** (dict) – A generic dictionary parameter. (default: ``{}``) - * **param_bare_list** (list) – A bare list parameter. (default: ``[]``) - Returns - ------- - None - Does not return anything. - """ - # Dedent the expected docstring for accurate comparison - expected_docstring = textwrap.dedent(expected_docstring).strip() - - # Get the decorated function's docstring and dedent it before comparison - decorated_docstring = textwrap.dedent(dummy_plot_function.__doc__).strip() - # Assert that the docstrings are a perfect match - assert decorated_docstring == expected_docstring + # Get the decorated function's docstring + decorated_docstring = dummy_plot_function.__doc__ + + # Assert that the core parts of the original and generated docstrings are present + assert "This is the original docstring." in decorated_docstring + assert "Parameters" in decorated_docstring + assert "data : dict" in decorated_docstring + assert "Returns" in decorated_docstring + assert "Does not return anything." in decorated_docstring + + # Assert that the kwargs section and its description are present + assert "**kwargs" in decorated_docstring + assert "Keyword arguments for plot configuration." in decorated_docstring + assert "``TestModel`` Pydantic model" in decorated_docstring + + # Assert that each parameter is present with its correct type and default value + assert "* **param_str** (str) – A string parameter." in decorated_docstring + assert ( + "* **param_int** (int) – An integer parameter with a default. (default: ``5``)" + in decorated_docstring + ) + assert ( + "* **param_list** (list of str) – An optional list of strings." + in decorated_docstring + ) + assert ( + "* **param_dict** (dict) – A generic dictionary parameter. (default: ``{}``)" + in decorated_docstring + ) + assert ( + "* **param_bare_list** (list) – A bare list parameter. (default: ``[]``)" + in decorated_docstring + ) From 2b303bb82f2f2cc52561cf7f41045b5730393fc5 Mon Sep 17 00:00:00 2001 From: sayalaruano Date: Wed, 10 Sep 2025 16:52:23 +0200 Subject: [PATCH 32/32] =?UTF-8?q?=F0=9F=90=9B=20Fix(src/vuecore/utils/docs?= =?UTF-8?q?=5Futils.py):=20removeunnecesary=20fstring=20in=20one=20of=20th?= =?UTF-8?q?e=20elemnts=20of=20the=20list=20to=20avoid=20ruff=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vuecore/utils/docs_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vuecore/utils/docs_utils.py b/src/vuecore/utils/docs_utils.py index c056430..8ebf563 100644 --- a/src/vuecore/utils/docs_utils.py +++ b/src/vuecore/utils/docs_utils.py @@ -130,7 +130,7 @@ def wrapper(*args, **kwargs): " **kwargs", " Keyword arguments for plot configuration. These arguments are validated against", f" the ``{model.__name__}`` Pydantic model and the engine specific parameters.\n", - f" The following parameters are supported:\n", + " The following parameters are supported:\n", ] # Add all parameter lines