open-feature / open-feature/python-sdk
Is InMemoryFlag.state intended to be honoured? DISABLED is never read
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 111
- Forks
- 44
- Merge moyen
- 2 h 37 min
- PR mergées (30 j)
- 14
Description
InMemoryFlag declares a state field with an ENABLED/DISABLED enum, and as far as I can tell nothing ever reads it. Asking because "the field is there for API compatibility and honouring it was never promised" is a perfectly good answer, and I would rather have it recorded than assume a bug.
What I see
openfeature/provider/in_memory_provider.py:
class InMemoryFlag(typing.Generic[T_co]):
class State(StrEnum):
ENABLED = "ENABLED"
DISABLED = "DISABLED"
default_variant: str
variants: dict[str, T_co]
flag_metadata: FlagMetadata = field(default_factory=dict)
state: State = State.ENABLED # line 47
...
def resolve(self, evaluation_context):
if self.context_evaluator:
return self.context_evaluator(self, evaluation_context or EvaluationContext())
return FlagResolutionDetails(
value=self.variants[self.default_variant],
reason=Reason.STATIC,
variant=self.default_variant,
flag_metadata=self.flag_metadata,
)
grep -n state in_memory_provider.py returns exactly one line — the declaration above. State.DISABLED does not appear anywhere else in the package.
So a flag constructed with state=State.DISABLED resolves to its own defaultVariant with reason STATIC, as though it were enabled.
Why I think it may be worth changing
For comparison, across the other in-memory reference providers:
| SDK | field | behaviour on a disabled flag |
|---|---|---|
| JavaScript | disabled: boolean |
caller's default, reason: DISABLED, no error code |
| Java | disabled (isDisabled) |
caller's default, reason: DISABLED, no error code |
| Go | State enum |
caller's default + reason: DISABLED, but also a GENERAL error — reported as go-sdk#552, fixed by #574 |
| Python | state enum |
resolves as if enabled |
Two of the four substitute the caller's default with reason: DISABLED and no error; Go agreed that was the right answer when it was raised. That is convention rather than specification — I could find no numbered requirement saying what a provider owes a disabled flag — so this is not a conformance claim, just a consistency observation.
Also worth noting the two shapes in the ecosystem: state: ENABLED|DISABLED in Go, Python and flagd's flag format, versus disabled: boolean in JavaScript, Java and Appendix B's test-flags.json. Not something to fix here, but it is why the field probably exists in this shape.
Questions
- Is
stateintended to be honoured byresolve(), or is it carried for configuration compatibility only? - If it should be honoured — is the intended behaviour the caller's default with
reason: DISABLEDand no error code, matching JavaScript and Java? - Would you rather the field were removed than implemented, if honouring it is not wanted? A declared field that is never read seems the more surprising of the two states.
Context
Found while building the cross-language provider conformance suite proposed in open-feature/spec#417. A new gated @disabled-flags capability is left undeclared for the Python in-memory suites on the strength of this, and the four scenarios skip rather than fail — so nothing is blocked. Recording the question so the reason for that gate is not just in my head.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez dans openfeature/provider/in_memory_provider.py, au niveau de InMemoryFlag.state et de resolve(), puis comparez le comportement documenté entre les langages pour les flags désactivés décrit dans l’issue. Confirmez si Python doit respecter DISABLED ou conserver le champ uniquement pour des raisons de compatibilité. Le travail est terminé lorsque le comportement attendu a été décidé et consigné, et que le comportement pertinent du fournisseur en mémoire ou les tests ont été mis à jour si les maintainers décident d’un changement.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- api
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 38/100