{"record":{"id":"e4dda3549e97df0b","repo":"pytest-dev/pytest","slug":"invalid-specification-kw-r","errorCode":null,"errorMessage":"invalid specification {kw!r}","messagePattern":"invalid specification (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/_py/path.py","lineNumber":660,"sourceCode":"        the following keyword arguments modify various path parts::\n\n          a:/some/path/to/a/file.ext\n          xx                           drive\n          xxxxxxxxxxxxxxxxx            dirname\n                            xxxxxxxx   basename\n                            xxxx       purebasename\n                                 xxx   ext\n        \"\"\"\n        obj = object.__new__(self.__class__)\n        if not kw:\n            obj.strpath = self.strpath\n            return obj\n        drive, dirname, _basename, purebasename, ext = self._getbyspec(\n            \"drive,dirname,basename,purebasename,ext\"\n        )\n        if \"basename\" in kw:\n            if \"purebasename\" in kw or \"ext\" in kw:\n                raise ValueError(f\"invalid specification {kw!r}\")\n        else:\n            pb = kw.setdefault(\"purebasename\", purebasename)\n            try:\n                ext = kw[\"ext\"]\n            except KeyError:\n                pass\n            else:\n                if ext and not ext.startswith(\".\"):\n                    ext = \".\" + ext\n            kw[\"basename\"] = pb + ext\n\n        if \"dirname\" in kw and not kw[\"dirname\"]:\n            kw[\"dirname\"] = drive\n        else:\n            kw.setdefault(\"dirname\", dirname)\n        kw.setdefault(\"sep\", self.sep)\n        obj.strpath = normpath(\"{dirname}{sep}{basename}\".format(**kw))\n        return obj","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/_py/path.py#L642-L678","documentation":"Raised by legacy pytest.path.LocalPath.new() when the keyword arguments used to derive a new path are internally contradictory. Specifically, passing 'basename' together with either 'purebasename' or 'ext' is rejected because basename already fully encodes both the pure base name and the extension, so specifying them alongside is ambiguous. The ValueError surfaces from the spec-resolution branch that validates kwargs before constructing the new path object.","triggerScenarios":"Calling path.new(basename='foo.txt', ext='.log') or path.new(basename='foo', purebasename='bar') — any call where kwargs simultaneously contains 'basename' and at least one of 'purebasename'/'ext'.","commonSituations":"Refactoring test helpers that built paths from components; migrating from older py.path.local APIs; copy-pasting a path construction that mixed basename-level and component-level overrides.","solutions":["Pass only 'basename', or only 'purebasename'/'ext' — never both at once.","If you need to change the extension, use new(purebasename=..., ext=...) and drop 'basename'.","If you need to set the full filename, use new(basename=...) alone.","Switch to the modern pathlib API (pathlib.Path.with_name / with_suffix) which has no such conflict."],"exampleFix":"// before\np.new(basename='report.txt', ext='.csv')\n// after\np.new(basename='report.csv')","handlingStrategy":"validation","validationCode":"def safe_new(path, **kw):\n    if 'basename' in kw and ('purebasename' in kw or 'ext' in kw):\n        raise ValueError(\"Pass 'basename' OR ('purebasename'/'ext'), not both\")\n    return path.new(**kw)","typeGuard":"def is_consistent_spec(kw: dict) -> bool:\n    return not ('basename' in kw and ('purebasename' in kw or 'ext' in kw))","tryCatchPattern":"try:\n    p = path.new(**kw)\nexcept ValueError as e:\n    if 'invalid specification' in str(e):\n        # resolve conflict and retry with single component\n        ...","preventionTips":["Decide upfront whether you compose from basename or from purebasename+ext.","Prefer pathlib.Path.with_name / with_suffix in new code."],"tags":["py-path","localpath","argument-validation"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}