-
Notifications
You must be signed in to change notification settings - Fork 685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new config types, improve existing types #2010
Conversation
63f6da2
to
007a582
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, that was quite a lot to review, but it looks solid. 🙌
This leaves me wondering if there isn't some other format (like TOML) or library (like Pydantic) we could use instead of rolling our own config subsystem. I realize that would be a breaking change and not the most productive thing to spend our spare time on, so I'll settle with a solid test suite :-)
9f93b26
to
feb53cd
Compare
The thought had definitely occurred to me too, but yeah, it's obviously a significant amount of work and BC breakage. For the record, I'd be strongly opposed to implementing Pydantic. I'm not a fan of how it requires your domain models to inherit from their base classes, and all the potential problems that can bring. While I'm not wedded to it, I've had a lot of success with marshmallow for serialisation+deserialisation, and plain old dataclasses from the stdlib for the domain models. In fact, I've even considered whether it would be worth swapping out the existing models implementation for this paradigm. In python 3.10, dataclasses support automatically generating |
I've done the rounds through attrs, dataclasses, and Pydantic, and have been quite happy with all of them. I'd use dataclasses for any library that doesn't strictly need more. dataclasses with slots and immutability sounds like a good fit for Mopidy's models, but that still leaves the validation part to us. |
I had a random look at some projects in this space yesterday but never used any of them (Mopidy is still my only Python project!). Maybe we should start a new issue/discussion about this topic. Currently I'm not convinced any switch is worth it, we'd always end up having to write extra validators anyway. |
That discussion is clearly too long-term to block this PR. Do you want to give this a review before we merge, @kingosticks ? |
subtype.deserialize(v.strip()) for v in values if v.strip() | ||
) | ||
if self._unique: | ||
values = frozenset(values_iter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may return a different order compared to the value. I think that would be unexpected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much of a concern is it likely to be? The behaviour is opt-in, so I guess we can always adjust the behaviour later based on feedback if absolutely necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it was documented it'd be better. I just don't like the surprise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a comment 👍
If you rebase you'll pick up the flake8 fix |
feb53cd
to
ec3ab45
Compare
- Added new Float type. It's very similar to the existing Integer type, but accepts floating point numbers, and doesn't allow you to set choices. - Added new Pair type, for when you want to accept a pair of values in a single config setting. Pairs default to a pair of strings, but you can set either subtype to whatever type you want (including nested pairs). - Added transformer property to String type. This allows you to apply an arbitrary transformation to individual config settings that could utimately be anything at all. - If a transformation is applied to a String config value, it will now return a subclass of the built-in str type. This subclass stores the original value as well as the transformed value, so that it can be re-serialised correctly. - The "Expected Path" type originally created for the Path type is (for now) just a subclass of the "Transformed Value" class, due to the duplicate implementation. In future, this should be updated to return pathlib Path objects, not strings. - Made Secret type pass through the transformer property correctly to its String parent class. - Lists can now return a frozenset instead of a tuple, configured by the "unique" property. - Lists now accept an arbitrary subtype, similar to the Pair type. This can be any type at all, including Pairs. - Resolved a couple of todo comments regarding missing tests for the List type. - The Path type will now correctly serialise None to an empty string.
ec3ab45
to
6f55166
Compare
I've rebased the branch and added a changelog entry 👍 |
but accepts floating point numbers, and doesn't allow you to set
choices.
single config setting. Pairs default to a pair of strings, but you can
set either subtype to whatever type you want (including nested pairs).
arbitrary transformation to individual config settings that could
utimately be anything at all.
return a subclass of the built-in str type. This subclass stores the
original value as well as the transformed value, so that it can be
re-serialised correctly.
now) just a subclass of the "Transformed Value" class, due to the
duplicate implementation. In future, this should be updated to return
pathlib Path objects, not strings.
its String parent class.
"unique" property.
can be any type at all, including Pairs.
List type.