{"record":{"id":"5d507e95c607c3d0","repo":"pypa/pip","slug":"name-name-r-is-not-normalized","errorCode":null,"errorMessage":"Name {name!r} is not normalized","messagePattern":"Name (.+?) is not normalized","errorType":"validation","errorClass":"PylockValidationError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/pylock.py","lineNumber":241,"sourceCode":"    except Exception as e:\n        raise PylockValidationError(e, context=f\"{key}[{len(result)}]\") from e\n    return result\n\n\ndef _get_required_sequence_of_objects(\n    d: Mapping[str, Any], target_item_type: type[_FromMappingProtocolT], key: str\n) -> Sequence[_FromMappingProtocolT]:\n    \"\"\"Get a required list value from the dictionary and convert its items to a\n    dataclass.\"\"\"\n    if (result := _get_sequence_of_objects(d, target_item_type, key)) is None:\n        raise _PylockRequiredKeyError(key)\n    return result\n\n\ndef _validate_normalized_name(name: str) -> NormalizedName:\n    \"\"\"Validate that a string is a NormalizedName.\"\"\"\n    if not is_normalized_name(name):\n        raise PylockValidationError(f\"Name {name!r} is not normalized\")\n    return NormalizedName(name)\n\n\ndef _validate_path_url(path: str | None, url: str | None) -> None:\n    if not path and not url:\n        raise PylockValidationError(\"path or url must be provided\")\n\n\ndef _path_name(path: str | None) -> str | None:\n    if not path:\n        return None\n    # If the path is relative it MAY use POSIX-style path separators explicitly\n    # for portability\n    if \"/\" in path:\n        return path.rsplit(\"/\", 1)[-1]\n    elif \"\\\\\" in path:\n        return path.rsplit(\"\\\\\", 1)[-1]\n    else:","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/pylock.py#L223-L259","documentation":"Raised by _validate_normalized_name in pylock.py:238-242, invoked for the package 'name' and for each 'extras' entry. The value must already be PEP 503 normalized (lowercase, with runs of '-', '_', '.' collapsed to a single '-'); otherwise PylockValidationError is raised.","triggerScenarios":"In pylock TOML: name = \"My_Package\", name = \"Foo.Bar\", name = \"Requests\", or extras = [\"Test_Extra\"].","commonSituations":"Copying a PyPI display/project name verbatim; carrying underscores or mixed case over from setup.py; tooling that does not canonicalize before emitting the lock file.","solutions":["Normalize the name first with packaging.utils.canonicalize_name before writing it (e.g. 'My_Package' -> 'my-package')."],"exampleFix":"# before\n[[packages]]\nname = \"My_Package\"\n# after\n[[packages]]\nname = \"my-package\"","handlingStrategy":"validation","validationCode":"from packaging.utils import canonicalize_name, is_normalized_name\n\ndef normalized(name: str) -> str:\n    return canonicalize_name(name)\n\ndef already_normalized(name: str) -> bool:\n    return is_normalized_name(name)\n","typeGuard":"from packaging.utils import is_normalized_name, NormalizedName\n\ndef is_normalized_pkgname(name: str) -> bool:\n    return is_normalized_name(name)\n","tryCatchPattern":"from packaging.pylock import Pylock, PylockValidationError\n\ntry:\n    Pylock.from_dict(d)\nexcept PylockValidationError as e:\n    ...\n","preventionTips":["Run names through packaging.utils.canonicalize_name before writing them to a pylock file.","Treat PyPI display names as un-normalized input."],"tags":["pylock","pep503","validation","naming"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}