{"record":{"id":"28bebb314313fd05","repo":"pypa/pip","slug":"entrypoint-must-be-in-name-module-attrs-extras","errorCode":null,"errorMessage":"EntryPoint must be in 'name=module:attrs [extras]' format","messagePattern":"EntryPoint must be in 'name=module:attrs \\[extras\\]' format","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pkg_resources/__init__.py","lineNumber":2798,"sourceCode":"        r'(:\\s*(?P<attr>[\\w.]+))?\\s*'\n        r'(?P<extras>\\[.*\\])?\\s*$'\n    )\n\n    @classmethod\n    def parse(cls, src: str, dist: Distribution | None = None):\n        \"\"\"Parse a single entry point from string `src`\n\n        Entry point syntax follows the form::\n\n            name = some.module:some.attr [extra1, extra2]\n\n        The entry name and module name are required, but the ``:attrs`` and\n        ``[extras]`` parts are optional\n        \"\"\"\n        m = cls.pattern.match(src)\n        if not m:\n            msg = \"EntryPoint must be in 'name=module:attrs [extras]' format\"\n            raise ValueError(msg, src)\n        res = m.groupdict()\n        extras = cls._parse_extras(res['extras'])\n        attrs = res['attr'].split('.') if res['attr'] else ()\n        return cls(res['name'], res['module'], attrs, extras, dist)\n\n    @classmethod\n    def _parse_extras(cls, extras_spec):\n        if not extras_spec:\n            return ()\n        req = Requirement.parse('x' + extras_spec)\n        if req.specs:\n            raise ValueError\n        return req.extras\n\n    @classmethod\n    def parse_group(\n        cls,\n        group: str,","sourceCodeStart":2780,"sourceCodeEnd":2816,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/pkg_resources/__init__.py#L2780-L2816","documentation":"Raised as ValueError in EntryPoint.parse when the input string does not match the entry point pattern regex. The expected format is 'name=module:attrs [extras]' — name and module are required, attrs and extras are optional. The regex at line 2775-2781 requires an '=' sign separating name from module.","triggerScenarios":"Calling EntryPoint.parse() with a malformed string — missing '=', missing module after '=', unparseable extras brackets, or stray characters. This also fires when parsing entry_points.txt metadata that contains a malformed line.","commonSituations":"Hand-editing entry_points.txt with syntax errors; tools that generate entry point strings with missing '=' or wrong separators; copy-paste errors in setup.cfg/pyproject.toml [project.scripts]; whitespace or encoding issues in the metadata.","solutions":["Verify the string matches 'name = module.path:attribute [extra1,extra2]' format with an '=' sign.","Check for missing or misplaced '=' — it must separate the entry name from the module path.","Ensure extras (if present) are in square brackets and comma-separated.","Use setuptools' entry_points dict/list validators instead of writing raw strings."],"exampleFix":"// before\nEntryPoint.parse('mycli mypkg.cli:main')\n# ValueError: must be in 'name=module:attrs [extras]' format\n\n// after\nEntryPoint.parse('mycli = mypkg.cli:main')","handlingStrategy":"validation","validationCode":"import re\nEP_PATTERN = re.compile(r'\\s*(?P<name>.+?)\\s*=\\s*(?P<module>[\\w.]+)\\s*(:\\s*(?P<attr>[\\w.]+))?\\s*(?P<extras>\\[.*\\])?\\s*$')\ndef is_valid_entry_point_string(s: str) -> bool:\n    return bool(EP_PATTERN.match(s))","typeGuard":"import re\ndef is_parseable_entry_point(s: str) -> bool:\n    return bool(re.match(r'^\\s*.+?\\s*=\\s*[\\w.]+\\s*(:\\s*[\\w.]+)?\\s*(\\[.*\\])?\\s*$', s))\n","tryCatchPattern":"from pkg_resources import EntryPoint\ntry:\n    ep = EntryPoint.parse(raw_string)\nexcept ValueError:\n    # log malformed entry point; skip it\n    ep = None\n","preventionTips":["Validate entry point strings before parsing.","Use setup.cfg/pyproject.toml entry_points sections with correct syntax.","Run setup.py egg_info and inspect generated entry_points.txt before release."],"tags":["entry-points","pkg-resources","parsing","format-error"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}