{"record":{"id":"bcd57bdfc8ef3007","repo":"pytest-dev/pytest","slug":"mode-mode-r-must-be-an-integer","errorCode":null,"errorMessage":"mode {mode!r} must be an integer","messagePattern":"mode (.+?) must be an integer","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/_py/path.py","lineNumber":1039,"sourceCode":"\n    def atime(self):\n        \"\"\"Return last access time of the path.\"\"\"\n        return self.stat().atime\n\n    def __repr__(self):\n        return f\"local({self.strpath!r})\"\n\n    def __str__(self):\n        \"\"\"Return string representation of the Path.\"\"\"\n        return self.strpath\n\n    def chmod(self, mode, rec=0):\n        \"\"\"Change permissions to the given mode. If mode is an\n        integer it directly encodes the os-specific modes.\n        if rec is True perform recursively.\n        \"\"\"\n        if not isinstance(mode, int):\n            raise TypeError(f\"mode {mode!r} must be an integer\")\n        if rec:\n            for x in self.visit(rec=rec):\n                error.checked_call(os.chmod, str(x), mode)\n        error.checked_call(os.chmod, self.strpath, mode)\n\n    def pypkgpath(self):\n        \"\"\"Return the Python package path by looking for the last\n        directory upwards which still contains an __init__.py.\n        Return None if a pkgpath cannot be determined.\n        \"\"\"\n        pkgpath = None\n        for parent in self.parts(reverse=True):\n            if parent.isdir():\n                if not parent.join(\"__init__.py\").exists():\n                    break\n                if not isimportable(parent.basename):\n                    break\n                pkgpath = parent","sourceCodeStart":1021,"sourceCodeEnd":1057,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/_py/path.py#L1021-L1057","documentation":"Raised by LocalPath.chmod() when the mode argument is not an int. The method delegates to os.chmod, which requires a numeric permission bitmask (e.g. 0o755). Passing a string like '755' or 'rwxr-xr-x' is rejected with a TypeError before any filesystem call.","triggerScenarios":"Calling path.chmod('755'); passing an octal literal as a string; passing None or a permission object instead of an int.","commonSituations":"Config-driven code that reads permission strings from YAML/ENV; shell-script-to-Python porting where chmod accepted string modes; forgetting the 0o prefix.","solutions":["Pass an integer octal literal: path.chmod(0o755).","Convert config strings: path.chmod(int(mode_str, 8)).","Validate the mode is an int before calling."],"exampleFix":"// before\np.chmod('755')\n// after\np.chmod(0o755)","handlingStrategy":"validation","validationCode":"def safe_chmod(path, mode):\n    if isinstance(mode, str):\n        mode = int(mode, 8)\n    if not isinstance(mode, int):\n        raise TypeError('mode must be int or octal string')\n    path.chmod(mode)","typeGuard":"def is_int_mode(mode) -> bool:\n    return isinstance(mode, int) and not isinstance(mode, bool)","tryCatchPattern":null,"preventionTips":["Always use 0o-prefixed octal literals.","Convert config strings with int(value, 8) at the boundary."],"tags":["py-path","localpath","filesystem","type-mismatch"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}