{"record":{"id":"ee86a88f9353c081","repo":"pypa/pip","slug":"unexpected-type-type-value-name-expected-s","errorCode":null,"errorMessage":"Unexpected type {type(value).__name__} (expected Sequence)","messagePattern":"Unexpected type (.+?) \\(expected Sequence\\)","errorType":"validation","errorClass":"PylockValidationError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/pylock.py","lineNumber":135,"sourceCode":"    return value\n\n\ndef _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T:\n    \"\"\"Get a required value from the dictionary and verify it's the expected type.\"\"\"\n    if (value := _get(d, expected_type, key)) is None:\n        raise _PylockRequiredKeyError(key)\n    return value\n\n\ndef _get_sequence(\n    d: Mapping[str, Any], expected_item_type: type[_T], key: str\n) -> Sequence[_T] | None:\n    \"\"\"Get a list value from the dictionary and verify it's the expected items type.\"\"\"\n    if (value := _get(d, Sequence, key)) is None:  # type: ignore[type-abstract]\n        return None\n    if isinstance(value, (str, bytes)):\n        # special case: str and bytes are Sequences, but we want to reject it\n        raise PylockValidationError(\n            f\"Unexpected type {type(value).__name__} (expected Sequence)\",\n            context=key,\n        )\n    for i, item in enumerate(value):\n        if not isinstance(item, expected_item_type):\n            raise PylockValidationError(\n                f\"Unexpected type {type(item).__name__} \"\n                f\"(expected {expected_item_type.__name__})\",\n                context=f\"{key}[{i}]\",\n            )\n    return value\n\n\ndef _get_as(\n    d: Mapping[str, Any],\n    expected_type: type[_T],\n    target_type: Callable[[_T], _T2],\n    key: str,","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/pylock.py#L117-L153","documentation":"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).","triggerScenarios":"In pylock TOML: dependencies = \"requests\" (string, expected array), environments = \"python_version >= '3.9'\" (expected array of marker strings), extras = \"test\" (expected array).","commonSituations":"Writing a scalar where the spec wants a list; forgetting square brackets around a single-element array.","solutions":["Wrap the value in square brackets to make it a TOML array."],"exampleFix":"# before\n[[packages]]\ndependencies = \"requests\"\n# after\n[[packages]]\ndependencies = [\"requests\"]","handlingStrategy":"type-guard","validationCode":"def ensure_array(key: str, value):\n    if isinstance(value, (str, bytes)):\n        raise TypeError(f\"{key} must be an array, got {type(value).__name__}\")\n    return value\n","typeGuard":"from collections.abc import Sequence\n\ndef is_real_sequence(value) -> bool:\n    return isinstance(value, Sequence) and not isinstance(value, (str, bytes))\n","tryCatchPattern":"from packaging.pylock import Pylock, PylockValidationError\n\ntry:\n    Pylock.from_dict(d)\nexcept PylockValidationError as e:\n    ...\n","preventionTips":["Always use TOML arrays ([...]) for list-valued pylock fields.","Reject str/bytes at your own TOML-loading boundary before handing to pylock."],"tags":["pylock","toml","validation","type"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}