An abstract base shares one provider's declarations - #301
Merged
Conversation
czpython
force-pushed
the
abstract-service-bases
branch
from
August 22, 2026 08:41
b0c7b89 to
a1bdc69
Compare
czpython
enabled auto-merge (squash)
August 22, 2026 08:41
czpython
force-pushed
the
abstract-service-bases
branch
from
August 22, 2026 08:44
a1bdc69 to
43216b5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
One provider often backs several services — Google backs Gmail and Google Calendar, and each keeps its own card, its own key, and its own blast radius. Until now every one of them re-declared the provider's OAuth quirks: both endpoints,
extra_authorize_params = {"access_type": "offline", "prompt": "consent"}, the identity endpoint and its scopes, and the same two-fieldSettings.Servicenow acceptsabstract = True. An abstract base never registers and skips validation; each subclass inherits everything the base declares —Settingsincluded, since the validator now readsSettingsthrough inheritance — and registers itself:The contract stays loud:
abstractmust be set in the class's own body (it never leaks to children), a class that sets bothabstractandnameraises at definition, a concrete subclass that forgetsnamestill raises, and a base declaring only one OAuth endpoint fails on its first concrete subclass — the endpoint checks read through the MRO. Typing improves too: the base's declarations are checked againstService'sClassVarannotations, so a wrong-shaped quirk fails pyright at the definition site instead of surfacing at runtime.