feat(core): pass bound domain to provider initialize and enforce domain-scoped binding#616
feat(core): pass bound domain to provider initialize and enforce domain-scoped binding#616jonathannorris wants to merge 8 commits into
Conversation
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
|
Warning Review limit reached
Next review available in: 54 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds an optional ChangesDomain-aware provider initialization
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client as API/Client
participant Registry as ProviderRegistry
participant Provider as FeatureProvider
Client->>Registry: set_provider(domain, provider, wait_for_init=True)
Registry->>Registry: _reject_domain_scoped_rebind(provider, domain)
alt provider.domain_scoped and already bound to different domain
Registry-->>Client: raise GeneralError
else binding allowed
Registry->>Registry: _initialize_accepts_domain(provider.initialize)
alt initialize accepts domain
Registry->>Provider: initialize(evaluation_context, domain=domain)
else legacy signature
Registry->>Provider: initialize(evaluation_context)
end
Provider-->>Registry: status READY / error
Registry-->>Client: provider bound and initialized
end
Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #616 +/- ##
==========================================
+ Coverage 98.34% 98.55% +0.20%
==========================================
Files 45 46 +1
Lines 2483 2698 +215
==========================================
+ Hits 2442 2659 +217
+ Misses 41 39 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the provider registry initialization flow to pass the bound domain into provider initialize(...) (while preserving backward compatibility for legacy single-argument initialize(context) implementations) and introduces an opt-in domain_scoped provider declaration that prevents the same provider instance from being bound to multiple domains.
Changes:
- Extend
FeatureProvider.initializeto accept an optionaldomainargument and pass the bound domain fromProviderRegistryduring initialization. - Add
domain_scopedsupport and enforce single-domain binding for domain-scoped provider instances. - Add/adjust API + registry tests, including a legacy provider fixture to validate backward compatibility.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/test_api.py | Updates API-level expectations for initialize(..., domain=...) and adds domain-scoped/legacy coverage. |
| tests/provider/test_registry.py | Adds registry-focused tests for domain passing, domain-scoped binding enforcement, and signature-compat behavior. |
| tests/legacy_init_provider.py | Introduces a legacy provider fixture implementing initialize(context) only. |
| openfeature/provider/_registry.py | Implements domain-aware initialization dispatch and domain-scoped rebind enforcement. |
| openfeature/provider/init.py | Updates the provider protocol/base class to include domain in initialize and adds a domain_scoped declaration hook. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if "domain_scoped" in getattr(provider, "__dict__", {}): | ||
| return bool(provider.__dict__["domain_scoped"]) | ||
| class_value = getattr(type(provider), "domain_scoped", False) | ||
| if isinstance(class_value, bool): | ||
| return class_value | ||
| return False | ||
|
|
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
openfeature/provider/_registry.py (1)
1-4: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffKeep
unittest.mockout of the registry runtime path._initialize_accepts_domainstill imports and branches onMockduring provider registration. If this is only for test doubles, move the compatibility shim into test helpers and rely on the callable signature in production code.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@openfeature/provider/_registry.py` around lines 1 - 4, The registry runtime path still depends on unittest.mock through the _initialize_accepts_domain logic in _registry.py, which should be removed from production registration flow. Update the provider registration path to rely on the callable signature inspection in _initialize_accepts_domain without importing or branching on Mock, and move any test-double compatibility handling into test-only helpers or fixtures so the registry stays free of unittest.mock at runtime.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@openfeature/provider/_registry.py`:
- Around line 1-4: The registry runtime path still depends on unittest.mock
through the _initialize_accepts_domain logic in _registry.py, which should be
removed from production registration flow. Update the provider registration path
to rely on the callable signature inspection in _initialize_accepts_domain
without importing or branching on Mock, and move any test-double compatibility
handling into test-only helpers or fixtures so the registry stays free of
unittest.mock at runtime.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: af35abb4-85c5-4a13-a422-6f4002c375b5
📒 Files selected for processing (5)
openfeature/provider/__init__.pyopenfeature/provider/_registry.pytests/legacy_init_provider.pytests/provider/test_registry.pytests/test_api.py
Summary
domainparameter to providerinitializeand pass the bound domain from the provider registry (spec 1.1.2.2, 2.4.1)domain_scopedprovider declaration and reject binding a domain-scoped instance to more than one domain (spec 2.4.3, 1.1.8.1)initializebackward compatibilityMotivation
Unblocks OFREP static-context providers that need the bound
domainat init time to scope persisted cache keys per open-feature/spec#393 and protocol ADR 0009.Notes
domainis an optional second parameter toinitializeinitializeruns once)initialize(context)remain compatible; the registry inspects theinitializesignature and omitsdomainwhen it is not acceptedRelated Issues
Closes #615
Relates to: open-feature/spec#393
Test plan
pytest(180 tests)