You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A boolean flag satisfies an Integer request: bool is a subclass of int #619
A boolean flag satisfies an Integer request. Evaluating a boolean flag through get_integer_details returns True with reason STATIC and no error code, where the specification requires the code default and TYPE_MISMATCH.
The application sees a plausible value — True behaves as 1 in arithmetic — and no indication that anything went wrong. That is the worst failure mode a feature flag has.
bool is a subclass of int in Python, so isinstance(True, int) is True and the check passes:
>>> isinstance(True, int)
True
The reverse direction is fine — isinstance(1, float) is False, so an integer requested as a float is correctly a mismatch — which is why this is easy to miss.
Reject bool explicitly when an integer or float was requested:
ifflag_typein (FlagType.INTEGER, FlagType.FLOAT) andisinstance(value, bool):
returnTypeMismatchError(f"Expected type {py_type} but got {type(value)}")
Worth checking the same place for FlagType.OBJECT: (dict, list) accepts a list, which is correct per the spec's structure type, but is worth a test either way.
How it surfaced
Building the Python implementation of the cross-language provider conformance suite (spec#417). The suite runs an identical type-mismatch matrix against every provider in every language; this row passes everywhere else and fails only in Python, because only Python has bool as a subclass of int.
That is a reasonable advertisement for having more than one language implementation: a Java or Go suite could never have caught this.
The suite currently marks the case xfail(strict=True) with a pointer to this issue, so it stays visible and un-hides itself automatically once this is fixed.
Thanks for the clear reproduction. I confirmed the behavior with InMemoryProvider and opened #621.
The fix rejects booleans for integer requests while preserving other integer subclasses. I also found that the async type-mismatch path reported the error but still returned the rejected value, so the PR makes it return the caller’s default as well.
I checked the in-memory conformance test from open-feature/python-sdk-contrib#409 too: the case marked for this issue now passes with the patch. The PR includes a runnable before/after example and regression tests for both sync and async getters.
Activity
feat: enforce reasons, and let a single scenario carry a known deviation
fix: reject boolean values for integer flags
Hexecu commentedon Aug 30, 2026
Thanks for the clear reproduction. I confirmed the behavior with
InMemoryProviderand opened #621.The fix rejects booleans for integer requests while preserving other integer subclasses. I also found that the async type-mismatch path reported the error but still returned the rejected value, so the PR makes it return the caller’s default as well.
I checked the in-memory conformance test from open-feature/python-sdk-contrib#409 too: the case marked for this issue now passes with the patch. The PR includes a runnable before/after example and regression tests for both sync and async getters.
fix: reject boolean values for integer flags (#621)
feat: enforce reasons, and let a single scenario carry a known deviation
feat: enforce reasons, and let a single scenario carry a known deviation
feat: enforce reasons, and let a single scenario carry a known deviation
feat: enforce reasons, and let a single scenario carry a known deviation
feat: enforce reasons, and let a single scenario carry a known deviation
test(ofrep): run the provider conformance suite against flagd's OFREP…
feat: enforce reasons, and let a single scenario carry a known deviation
feat: enforce reasons, and let a single scenario carry a known deviation
test(ofrep): run the provider conformance suite against flagd's OFREP…
feat: enforce reasons, and let a single scenario carry a known deviation
46 remaining items
test(ofrep): run the provider conformance suite against flagd's OFREP…
test(ofrep): run the provider conformance suite against flagd's OFREP…
feat: enforce reasons, and let a single scenario carry a known deviation
test(ofrep): run the provider conformance suite against flagd's OFREP…
feat: enforce reasons, and let a single scenario carry a known deviation
feat(provider-tck): add the Python conformance suite for OpenFeature …
test(ofrep): run the provider conformance suite against flagd's OFREP…
feat: enforce reasons, and let a single scenario carry a known deviation
feat(provider-tck): add the Python conformance suite for OpenFeature …
test(ofrep): run the provider conformance suite against flagd's OFREP…
feat: enforce reasons, and let a single scenario carry a known deviation
test(ofrep): run the provider conformance suite against flagd's OFREP…
feat(provider-tck): add the Python conformance suite for OpenFeature …
test(ofrep): run the provider conformance suite against flagd's OFREP…
test(ofrep): run the provider conformance suite against flagd's OFREP…