pypa/pip · error · PylockValidationError

Unexpected type (expected Sequence)

Error message

Unexpected type {type(value).__name__} (expected Sequence)

What it means

Raised by _get_sequence in pylock.py:133-138. Although str and bytes are technically Sequences, the pylock spec requires a TOML array, so a str/bytes value is explicitly rejected with PylockValidationError (context = key).

Solutions

  1. Wrap the value in square brackets to make it a TOML array.

Example fix

# before
[[packages]]
dependencies = "requests"
# after
[[packages]]
dependencies = ["requests"]
Defensive patterns

Strategy: type-guard

Validate before calling

def ensure_array(key: str, value):
    if isinstance(value, (str, bytes)):
        raise TypeError(f"{key} must be an array, got {type(value).__name__}")
    return value

Type guard

from collections.abc import Sequence

def is_real_sequence(value) -> bool:
    return isinstance(value, Sequence) and not isinstance(value, (str, bytes))

Try / catch

from packaging.pylock import Pylock, PylockValidationError

try:
    Pylock.from_dict(d)
except PylockValidationError as e:
    ...

Prevention

When it happens

Trigger: In pylock TOML: dependencies = "requests" (string, expected array), environments = "python_version >= '3.9'" (expected array of marker strings), extras = "test" (expected array).

Common situations: Writing a scalar where the spec wants a list; forgetting square brackets around a single-element array.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/ee86a88f9353c081. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_vendor/packaging/pylock.py:135

    return value


def _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T:
    """Get a required value from the dictionary and verify it's the expected type."""
    if (value := _get(d, expected_type, key)) is None:
        raise _PylockRequiredKeyError(key)
    return value


def _get_sequence(
    d: Mapping[str, Any], expected_item_type: type[_T], key: str
) -> Sequence[_T] | None:
    """Get a list value from the dictionary and verify it's the expected items type."""
    if (value := _get(d, Sequence, key)) is None:  # type: ignore[type-abstract]
        return None
    if isinstance(value, (str, bytes)):
        # special case: str and bytes are Sequences, but we want to reject it
        raise PylockValidationError(
            f"Unexpected type {type(value).__name__} (expected Sequence)",
            context=key,
        )
    for i, item in enumerate(value):
        if not isinstance(item, expected_item_type):
            raise PylockValidationError(
                f"Unexpected type {type(item).__name__} "
                f"(expected {expected_item_type.__name__})",
                context=f"{key}[{i}]",
            )
    return value


def _get_as(
    d: Mapping[str, Any],
    expected_type: type[_T],
    target_type: Callable[[_T], _T2],
    key: str,

View on GitHub (pinned to f399c37189)