{"record":{"id":"b8d78c8b5fbf25f9","repo":"pytest-dev/pytest","slug":"invalid-part-specification-name-r","errorCode":null,"errorMessage":"invalid part specification {name!r}","messagePattern":"invalid part specification (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/_py/path.py","lineNumber":706,"sourceCode":"                res.append(parts[0])\n            elif name == \"dirname\":\n                res.append(self.sep.join(parts[:-1]))\n            else:\n                basename = parts[-1]\n                if name == \"basename\":\n                    res.append(basename)\n                else:\n                    i = basename.rfind(\".\")\n                    if i == -1:\n                        purebasename, ext = basename, \"\"\n                    else:\n                        purebasename, ext = basename[:i], basename[i:]\n                    if name == \"purebasename\":\n                        res.append(purebasename)\n                    elif name == \"ext\":\n                        res.append(ext)\n                    else:\n                        raise ValueError(f\"invalid part specification {name!r}\")\n        return res\n\n    def dirpath(self, *args, **kwargs):\n        \"\"\"Return the directory path joined with any given path arguments.\"\"\"\n        if not kwargs:\n            path = object.__new__(self.__class__)\n            path.strpath = dirname(self.strpath)\n            if args:\n                path = path.join(*args)\n            return path\n        return self.new(basename=\"\").join(*args, **kwargs)\n\n    def join(self, *args: os.PathLike[str], abs: bool = False) -> LocalPath:\n        \"\"\"Return a new path by appending all 'args' as path\n        components.  if abs=1 is used restart from root if any\n        of the args is an absolute path.\n        \"\"\"\n        sep = self.sep","sourceCodeStart":688,"sourceCodeEnd":724,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/_py/path.py#L688-L724","documentation":"Raised inside LocalPath._getbyspec() when a requested spec part name is not one of the recognized tokens ('drive','dirname','basename','purebasename','ext'). The method splits a comma-separated spec string and appends each requested part to the result; an unknown token falls through to the else branch and raises ValueError. This is an internal helper invoked by new() and parts().","triggerScenarios":"Calling path._getbyspec('drive,dirname,foo') directly with a typo; an internal caller (e.g. parts()) passing an unsupported spec token; monkeypatching or extending the spec vocabulary incorrectly.","commonSituations":"Direct misuse of the private _getbyspec API; bugs in plugins or forks that reference non-existent path components; typo in a spec string passed through from custom code.","solutions":["Use only the supported spec tokens: drive, dirname, basename, purebasename, ext.","Avoid calling the private _getbyspec directly — use the public .parts() or .purebasename/.ext properties.","If you need a custom decomposition, split the path string yourself with os.path or pathlib."],"exampleFix":"// before\nparts = p._getbyspec('dirname,stemname')\n// after\nparts = p._getbyspec('dirname,purebasename')","handlingStrategy":"validation","validationCode":"VALID_PARTS = {'drive','dirname','basename','purebasename','ext'}\ndef safe_getbyspec(path, spec):\n    names = [s.strip() for s in spec.split(',')]\n    bad = [n for n in names if n not in VALID_PARTS]\n    if bad:\n        raise ValueError(f'unknown parts: {bad}')\n    return path._getbyspec(spec)","typeGuard":"def is_valid_part(name: str) -> bool:\n    return name in {'drive','dirname','basename','purebasename','ext'}","tryCatchPattern":null,"preventionTips":["Avoid calling the private _getbyspec; use public properties.","If you must, validate each token against the known set first."],"tags":["py-path","localpath","internal-api","argument-validation"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}