Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

A boolean flag satisfies a Float request in flagd-core: bool is a subclass of int

未关闭 适合新手
#417 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
90/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
python
领域
backend

调研方向

从 tools/openfeature-flagd-core/src/openfeature/contrib/tools/flagd/core/flagd_core.py 开始,阅读 float 和 integer 类型映射、_check_type 以及 resolve_float_value。为请求为 Float 的 boolean 和请求为 Float 的 integer 添加回归测试,然后运行 flagd-core 测试。完成标准是:boolean 返回默认值并带有 TYPE_MISMATCH,而 integer 扩宽仍然返回 10.0。

由索引模型根据 Issue 内容生成。

描述

Summary

A boolean flag satisfies a Float request. FlagdCore.resolve_float_value on a boolean flag returns 1.0 with reason STATIC and no error code, where the specification requires the code default and TYPE_MISMATCH.

The application sees a plausible value and no indication that anything went wrong — the worst failure mode a feature flag has.

The sibling case for the integer accessor is already guarded here, and the equivalent bug in the SDK's own type check was open-feature/python-sdk#619, fixed by open-feature/python-sdk#621. This is the same Python quirk in the remaining direction.

Reproducing

from openfeature.contrib.tools.flagd.core.flagd_core import FlagdCore

core = FlagdCore()
core.set_flags(
    '{"flags":{"boolean-flag":{"state":"ENABLED",'
    '"variants":{"on":true,"off":false},"defaultVariant":"on"}}}'
)

print(core.resolve_float_value("boolean-flag", 0.1))
# value=1.0  reason=STATIC  error_code=None
# expected: value=0.1  reason=ERROR  error_code=TYPE_MISMATCH

core.resolve_integer_value("boolean-flag", 1)
# raises TypeMismatchError -- the integer path is already guarded

Observed output:

FLOAT   -> 1.0 | type float | reason STATIC | error_code None
INTEGER -> raised TypeMismatchError (the existing guard works)

Cause

Two things combine in tools/openfeature-flagd-core/src/openfeature/contrib/tools/flagd/core/flagd_core.py.

The float entry in the type map is wider than the integer one (lines 25-26):

"integer": ((int,), "int"),
"float": ((int, float), "float"),

and the bool guard in _check_type is conditioned on the integer type alone (line 223):

# For integer type, reject bool (since bool is subclass of int)
if flag_type == "integer" and isinstance(value, bool):
    raise TypeMismatchError(...)

bool is a subclass of int, so isinstance(True, (int, float)) is True and a boolean passes the float check. resolve_float_value then widens it (lines 113-114):

result = self._resolve(flag_key, default_value, ctx, "float")
if isinstance(result.value, int):
    result.value = float(result.value)

isinstance(True, int) is True, so float(True) gives 1.0.

The SDK cannot catch this one

Worth stating, because the fix for open-feature/python-sdk#619 might look as though it covers this. It does not, and it does not need to:

  • For the integer accessor the SDK's map is a bare int, so isinstance(True, int) passed and a boolean slipped through. That was #619, now fixed.
  • For the float accessor the SDK's map is a bare float, and isinstance(True, float) is False — so the SDK rejects a boolean correctly on its own.

But by the time the value reaches the SDK it is a genuine float 1.0, because resolve_float_value already converted it. The evidence is destroyed upstream. Only this package can catch it.

Suggested fix

Widen the guard that is already there by one condition:

if flag_type in ("integer", "float") and isinstance(value, bool):
    raise TypeMismatchError(
        f"Expected type {type_name} but got {type(value).__name__}"
    )

The comment above it ("since bool is subclass of int") applies verbatim to the float mapping, which is (int, float).

Two things worth a regression test either way: that boolean-flag requested as a Float is a mismatch, and that integer-flag requested as a Float still succeeds and still returns 10.0 rather than 10 — the widening on lines 113-114 is deliberate and must survive the fix.

How it surfaced

Running the Python implementation of the cross-language provider conformance suite (open-feature/spec#417) against a real flagd backend, in-process resolver. The suite runs an identical type-mismatch matrix against every provider in every language, and the row boolean-flag requested as Float passes in Go, Java and JavaScript and fails only in Python — because only Python has bool as a subclass of int.

It affects the in-process resolver only; RPC type-asserts correctly on the same row, which is what localises it to this package rather than to the flagd daemon or to the provider.

That is the second time this one Python quirk has been found by the suite, in two packages and two accessor directions — #619 was the first. A Java or Go suite could not have caught either.

主要语言
Python
星标
27
派生
33
平均合并
1 天 17 小时
30 天内合并 PR
15

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

open-feature/python-sdk-contrib 的其他 Issue

查看 open-feature/python-sdk-contrib 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。