Skip to content

Commit 04548b0

Browse files
authored
Fix downstream marshmallow schema cross-references (#170)
Use absolute cross-references in inherited marshmallow schema docstrings. Fixes downstream strict documentation builds.
2 parents fb5abce + aa4d4ba commit 04548b0

2 files changed

Lines changed: 52 additions & 36 deletions

File tree

RELEASE_NOTES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@
1515
## Bug Fixes
1616

1717
<!-- Here goes notable bug fixes that are worth a special mention or explanation -->
18+
19+
- Fix a cross-reference that broke downstream strict doc builds.

src/frequenz/quantities/experimental/marshmallow.py

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"""Custom marshmallow fields and schema.
55
66
This module provides custom marshmallow fields for quantities and
7-
a [`QuantitySchema`][.QuantitySchema] class to
7+
a [`QuantitySchema`][frequenz.quantities.experimental.marshmallow.QuantitySchema] class to
88
be used as base schema for dataclasses containing quantities.
99
1010
Danger:
@@ -43,38 +43,45 @@
4343

4444

4545
class _QuantityField(Field[Quantity]):
46-
"""A custom field for [`Quantity`][....Quantity] objects.
46+
"""A custom field for [`Quantity`][frequenz.quantities.Quantity] objects.
4747
4848
Supports per-field serialization configuration.
4949
5050
This class handles serialization and deserialization of ALL
51-
[`Quantity`][....Quantity] subclasses.
52-
The specific [`Quantity`][....Quantity] subclass is determined by the
53-
[`.field_type`][.field_type] attribute.
51+
[`Quantity`][frequenz.quantities.Quantity] subclasses.
52+
The specific [`Quantity`][frequenz.quantities.Quantity] subclass is determined by the
53+
[`.field_type`][frequenz.quantities.experimental.marshmallow._QuantityField.field_type]
54+
attribute.
5455
5556
* Deserialization auto-detects the type of deserialization (float or string)
5657
based on the input type.
5758
* Serialization uses either the schema's default or the per-field
5859
configuration found in the metadata.
5960
6061
We need distinct `_QuantityField` subclasses for each
61-
[`Quantity`][....Quantity] subclass, so
62-
they can be used in the [`TYPE_MAPPING`][..QuantitySchema.TYPE_MAPPING] in
63-
[`QuantitySchema`][..QuantitySchema].
62+
[`Quantity`][frequenz.quantities.Quantity] subclass, so
63+
they can be used in the
64+
[`TYPE_MAPPING`][frequenz.quantities.experimental.marshmallow.QuantitySchema.TYPE_MAPPING]
65+
in
66+
[`QuantitySchema`][frequenz.quantities.experimental.marshmallow.QuantitySchema].
6467
This class is not intended to be used directly.
6568
6669
Instead, we use the specific `_QuantityField` subclasses for each
67-
[`Quantity`][....Quantity].
68-
Each field subclass simply sets the [`.field_type`][.field_type]
69-
attribute to the corresponding [`Quantity`][....Quantity] subclass.
70-
71-
Those subclasses are stored in [`QUANTITY_FIELD_CLASSES`][..QUANTITY_FIELD_CLASSES]
72-
and are used for the [`TYPE_MAPPING`][..QuantitySchema.TYPE_MAPPING] in
73-
[`QuantitySchema`][..QuantitySchema].
70+
[`Quantity`][frequenz.quantities.Quantity].
71+
Each field subclass simply sets the
72+
[`.field_type`][frequenz.quantities.experimental.marshmallow._QuantityField.field_type]
73+
attribute to the corresponding [`Quantity`][frequenz.quantities.Quantity] subclass.
74+
75+
Those subclasses are stored in
76+
[`QUANTITY_FIELD_CLASSES`][frequenz.quantities.experimental.marshmallow.QUANTITY_FIELD_CLASSES]
77+
and are used for the
78+
[`TYPE_MAPPING`][frequenz.quantities.experimental.marshmallow.QuantitySchema.TYPE_MAPPING]
79+
in
80+
[`QuantitySchema`][frequenz.quantities.experimental.marshmallow.QuantitySchema].
7481
"""
7582

7683
field_type: Type[Quantity] | None = None
77-
"""The specific [`Quantity`][.....Quantity] subclass."""
84+
"""The specific [`Quantity`][frequenz.quantities.Quantity] subclass."""
7885

7986
def __init__(self, *args: Any, **kwargs: Any) -> None:
8087
"""Initialize the field."""
@@ -84,7 +91,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
8491
def _serialize(
8592
self, value: Quantity | None, attr: str | None, obj: Any, **kwargs: Any
8693
) -> Any:
87-
"""Serialize a [`Quantity`][.....Quantity] based on per-field configuration.
94+
"""Serialize a [`Quantity`][frequenz.quantities.Quantity] based on per-field configuration.
8895
8996
Args:
9097
value: The quantity to serialize, or `None`.
@@ -97,9 +104,11 @@ def _serialize(
97104
the raw base float value otherwise. `None` if `value` is `None`.
98105
99106
Raises:
100-
TypeError: If [`..field_type`][..field_type] is not set to a
101-
[`Quantity`][.....Quantity] subclass, or if
102-
`value` is not a [`Quantity`][.....Quantity]
107+
TypeError: If
108+
[`.field_type`][frequenz.quantities.experimental.marshmallow._QuantityField.field_type]
109+
is not set to a
110+
[`Quantity`][frequenz.quantities.Quantity] subclass, or if
111+
`value` is not a [`Quantity`][frequenz.quantities.Quantity]
103112
instance.
104113
"""
105114
if self.field_type is None or not issubclass(self.field_type, Quantity):
@@ -132,7 +141,7 @@ def _serialize(
132141
def _deserialize(
133142
self, value: Any, attr: str | None, data: Any, **kwargs: Any
134143
) -> Quantity:
135-
"""Deserialize a [`Quantity`][.....Quantity] from a float, int, or string.
144+
"""Deserialize a [`Quantity`][frequenz.quantities.Quantity] from a float, int, or string.
136145
137146
Args:
138147
value: The raw value to deserialize (float, int, or string).
@@ -144,8 +153,10 @@ def _deserialize(
144153
The deserialized quantity instance.
145154
146155
Raises:
147-
TypeError: If [`..field_type`][..field_type] is not set to a
148-
[`Quantity`][.....Quantity] subclass.
156+
TypeError: If
157+
[`.field_type`][frequenz.quantities.experimental.marshmallow._QuantityField.field_type]
158+
is not set to a
159+
[`Quantity`][frequenz.quantities.Quantity] subclass.
149160
ValidationError: If the input type is invalid or parsing fails
150161
(see [`marshmallow.ValidationError`][marshmallow.ValidationError]).
151162
"""
@@ -186,55 +197,55 @@ def _deserialize(
186197

187198

188199
class ApparentPowerField(_QuantityField):
189-
"""A custom field for [`ApparentPower`][....ApparentPower] objects."""
200+
"""A custom field for [`ApparentPower`][frequenz.quantities.ApparentPower] objects."""
190201

191202
field_type = ApparentPower
192203

193204

194205
class CurrentField(_QuantityField):
195-
"""A custom field for [`Current`][....Current] objects."""
206+
"""A custom field for [`Current`][frequenz.quantities.Current] objects."""
196207

197208
field_type = Current
198209

199210

200211
class EnergyField(_QuantityField):
201-
"""A custom field for [`Energy`][....Energy] objects."""
212+
"""A custom field for [`Energy`][frequenz.quantities.Energy] objects."""
202213

203214
field_type = Energy
204215

205216

206217
class FrequencyField(_QuantityField):
207-
"""A custom field for [`Frequency`][....Frequency] objects."""
218+
"""A custom field for [`Frequency`][frequenz.quantities.Frequency] objects."""
208219

209220
field_type = Frequency
210221

211222

212223
class PercentageField(_QuantityField):
213-
"""A custom field for [`Percentage`][....Percentage] objects."""
224+
"""A custom field for [`Percentage`][frequenz.quantities.Percentage] objects."""
214225

215226
field_type = Percentage
216227

217228

218229
class PowerField(_QuantityField):
219-
"""A custom field for [`Power`][....Power] objects."""
230+
"""A custom field for [`Power`][frequenz.quantities.Power] objects."""
220231

221232
field_type = Power
222233

223234

224235
class ReactivePowerField(_QuantityField):
225-
"""A custom field for [`ReactivePower`][....ReactivePower] objects."""
236+
"""A custom field for [`ReactivePower`][frequenz.quantities.ReactivePower] objects."""
226237

227238
field_type = ReactivePower
228239

229240

230241
class TemperatureField(_QuantityField):
231-
"""A custom field for [`Temperature`][....Temperature] objects."""
242+
"""A custom field for [`Temperature`][frequenz.quantities.Temperature] objects."""
232243

233244
field_type = Temperature
234245

235246

236247
class VoltageField(_QuantityField):
237-
"""A custom field for [`Voltage`][....Voltage] objects."""
248+
"""A custom field for [`Voltage`][frequenz.quantities.Voltage] objects."""
238249

239250
field_type = Voltage
240251

@@ -250,10 +261,13 @@ class VoltageField(_QuantityField):
250261
Temperature: TemperatureField,
251262
Voltage: VoltageField,
252263
}
253-
"""The mapping from [`Quantity`][....Quantity] subclasses to their corresponding field subclasses.
264+
"""The mapping from [`Quantity`][frequenz.quantities.Quantity] subclasses
265+
to their corresponding field subclasses.
254266
255-
This mapping is used in [`QuantitySchema.TYPE_MAPPING`][..QuantitySchema.TYPE_MAPPING] to
256-
determine the correct field class for each [`Quantity`][....Quantity]
267+
This mapping is used in
268+
[`QuantitySchema.TYPE_MAPPING`][frequenz.quantities.experimental.marshmallow.QuantitySchema.TYPE_MAPPING]
269+
to
270+
determine the correct field class for each [`Quantity`][frequenz.quantities.Quantity]
257271
subclass.
258272
"""
259273

@@ -327,4 +341,4 @@ class Config:
327341
"""
328342

329343
TYPE_MAPPING: dict[type, type[Field[Any]]] = QUANTITY_FIELD_CLASSES
330-
"""The field class to use for each [`Quantity`][.....Quantity] subclass."""
344+
"""The field class to use for each [`Quantity`][frequenz.quantities.Quantity] subclass."""

0 commit comments

Comments
 (0)