pytest-dev/pytest · error · TypeError

Expected a float string for option {name} of type float, but

Error message

Expected a float string for option {name} of type float, but got: {value!r}

What it means

Raised by Config._getini_ini (config/__init__.py:1935-1939) for an option of type 'float' when, in INI mode, the value is not a str. Symmetric to the int case: float(value) is only valid on strings, and a non-str means the value bypassed the normal text-parsing path.

Source

Thrown at src/_pytest/config/__init__.py:1937

            return shlex.split(value) if isinstance(value, str) else value
        elif type == "linelist":
            if isinstance(value, str):
                return [t for t in map(lambda x: x.strip(), value.split("\n")) if t]
            else:
                return value
        elif type == "bool":
            return _strtobool(str(value).strip())
        elif type == "string":
            return value
        elif type == "int":
            if not isinstance(value, str):
                raise TypeError(
                    f"Expected an int string for option {name} of type integer, but got: {value!r}"
                ) from None
            return int(value)
        elif type == "float":
            if not isinstance(value, str):
                raise TypeError(
                    f"Expected a float string for option {name} of type float, but got: {value!r}"
                ) from None
            return float(value)
        else:
            return self._getini_unknown_type(name, type, value)

    def _getini_toml(
        self,
        name: str,
        canonical_name: str,
        type: str,
        value: object,
        default: Any,
    ):
        """Handle TOML config values with strict type validation and no coercion.

        In TOML mode, values already have native types from TOML parsing.
        We validate types match expectations exactly, including list items.

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Pass float values as strings so float(value) coercion runs: '1.5' not 1.5.
  2. Use the standard CLI / TOML path for float options instead of mutating _inicfg.
  3. For TOML config, switch the option to toml mode where native floats are accepted directly (see error 55).

Example fix

# before
config._inicfg['timeout'] = ConfigValue(value=1.5, ...)

# after
config._inicfg['timeout'] = ConfigValue(value='1.5', ...)
Defensive patterns

Strategy: validation

Validate before calling

def coerce_float_str(value):
    if not isinstance(value, str):
        value = str(value)
    float(value)
    return value

Type guard

def is_float_str(value) -> bool:
    if not isinstance(value, str):
        return False
    try:
        float(value); return True
    except ValueError:
        return False

Try / catch

try:
    config.getini(name)
except (TypeError, ValueError):
    # convert to a float string and reload

Prevention

When it happens

Trigger: Injecting a native float into an ini-mode float option via direct _inicfg mutation or a custom override path; calling _getini_ini with a non-str for a float-typed option.

Common situations: Programmatic config injection in conftest/plugin code; partial mocks in test suites for pytest itself; refactors that hand native floats to a path expecting strings.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/ebf6886f6860904c.json. Report an issue: GitHub.