Fix downstream marshmallow schema cross-references - #170
Conversation
Signed-off-by: Mathias L. Baumann <mathias.baumann@frequenz.com>
d98c481 to
aa4d4ba
Compare
llucax
left a comment
There was a problem hiding this comment.
This is not broken. Things are building correctly, the docs are published correctly, with working links. Maybe you are using an older mkdocs version that doesn't support the new relative_crossrefs: true?
|
IIUC, this is to fix this @luca: https://github.com/frequenz-floss/frequenz-sdk-python/actions/runs/34107815364/job/101696786441?pr=1454 I'd like that to be merged, so that I can merge the steam boiler PR and get it released tomorrow. |
|
This is super weird, I don't think a project should ever be following or rendering docs from a dependency. But in any case the correct fix would be to use relative crossrefs in the SDK, which should be done automatically when upgrading to repo-config v0.19. |
|
I see that's blocked on the exhaustion checks, so I will look into them now. |
|
There seems something else going on, it seems for some reason now properdocs is being used to render docs instead of mkdocs 😱 |
llucax
left a comment
There was a problem hiding this comment.
The rest could be wrong too, I didn't check. So this fix might be valid, but we should keep the relative refs when it makes sense (maybe up to ...?). The idea about relative refs is to make refs shorter, and easier to understand, once you get ..... it is really hard to follow, so absolute refs make sense in those cases.
|
|
||
|
|
||
| class _QuantityField(Field[Quantity]): | ||
| """A custom field for [`Quantity`][....Quantity] objects. |
There was a problem hiding this comment.
OK, I see now that this is really wrong, it is using four .:
.-> the classfrequenz.quantities.experimental._QuantityField..-> the modulefrequenz.quantities.experimental...-> the parent packagefrequenz.quantities....->frequenz
I guess we don't get a failure here because this is a private symbol, so it is never rendered.
There was a problem hiding this comment.
The count is off by one, and there's an extra module level missing. Looking at AutorefsHook.expand_identifier in mkdocstrings-python, the first dot only marks the reference as relative and doesn't move anywhere; each additional dot walks up one parent. And the chain here starts at frequenz.quantities.experimental.marshmallow, the marshmallow module is a level of its own.
So for [`Quantity`][....Quantity] on the _QuantityField class docstring, the three walking dots go _QuantityField → marshmallow → experimental → frequenz.quantities, giving frequenz.quantities.Quantity. That's correct as written. Being private isn't what saves it.
| """The field class to use for each [`Quantity`][.....Quantity] subclass.""" | ||
| """The field class to use for each [`Quantity`][frequenz.quantities.Quantity] subclass.""" |
There was a problem hiding this comment.
In the SDK we get a failure here. This one is wrong too, 5 dots:
.-> the modulefrequenz.quantities.experimental..-> the parent packagefrequenz.quantities...->frequenz....-> the root....-> ???
This one is public, so no idea why it is not failing in this repo.
There was a problem hiding this comment.
Same off-by-one: TYPE_MAPPING → QuantitySchema → marshmallow → experimental → frequenz.quantities, so [.....Quantity] resolves to frequenz.quantities.Quantity and is correct here.
It doesn't fail in this repo because the walk starts at frequenz.quantities.experimental.marshmallow.QuantitySchema.TYPE_MAPPING. In the SDK the same docstring is re-rendered as frequenz.sdk.config.BaseConfigSchema.TYPE_MAPPING, since BaseConfigSchema subclasses QuantitySchema and the SDK sets inherited_members: true. Four levels up from there is frequenz, so it looks for frequenz.Quantity and finds nothing. The reference is right where it's written and wrong everywhere it's inherited.
|
I reproduced this outside both repos with two throwaway packages,
Both repos pin exactly the same doc toolchain,
The SDK isn't rendering the dependency's docs, it's rendering its own class. Turning on relative crossrefs in the SDK makes it worse, not better. With
Depth isn't really the criterion, what matters is whether the walk leaves the object that gets re-rendered elsewhere. I measured all three cases downstream. That makes this PR's scope right as it stands. Worth knowing that inheritance isn't the only trigger. In the repro a plain The underlying behaviour is an upstream bug and I've filed it as mkdocstrings/python#341. For an inherited member griffe hands the renderer an One detail from that investigation argues for merging this regardless of what upstream does. A red build is the lucky outcome: when the downstream package happens to define its own symbol with the colliding name, the reference resolves to it, the build passes under |
llucax
left a comment
There was a problem hiding this comment.
OK, so let's go with this one. Then we release v1.0.3 and bite the major bump that should have never happened, or sort of, the module is marked as experimental and says anything can break at any time (although history have told us that's a dumb idea, because as we saw right now, things will blow up in our face anyway, and we should avoid that).
Unrelated, but I would consider moving this marshmallow stuff from experimental (or to a different library).
…ss#1456) CI started failing on `v1.x.x` yesterday with three unrelated-looking config test failures. They come from the `frequenz-quantities` 1.0.2 release, which raised its `marshmallow` floor to 4 (frequenz-floss/frequenz-quantities-python#107) and thereby dragged `marshmallow` 4 into our environment for the first time. Marshmallow 4 dropped support for validators that return `False` instead of raising, which is what the config test dataclasses were doing, so the validation silently stopped happening. The fix is test-only, but there is a release notes entry because the same silent acceptance hits anyone who wrote boolean validators for their own config dataclasses. Heads-up for whoever reviews: the docs job on this PR will stay red, for a second and unrelated problem from the same `frequenz-quantities` 1.0.2 release. That one is a docstring in `frequenz-quantities` using a relative mkdocstrings cross-reference, which misresolves whenever it is rendered under a path other than the one it was written in, as happens here with `BaseConfigSchema` inheriting `QuantitySchema.TYPE_MAPPING`. It cannot be fixed on this side, only worked around by dropping documentation, and frequenz-floss/frequenz-quantities-python#170 already fixes it upstream. frequenz-floss#1455 is blocked on the same thing.
Use absolute cross-references in inherited marshmallow schema docstrings.
Fixes downstream strict documentation builds.