{"record":{"id":"f3e0074459a6b5d7","repo":"RustPython/RustPython","slug":"can-t-open-filename-s-error-s","errorCode":null,"errorMessage":"can't open '%(filename)s': %(error)s","messagePattern":"can't open '(.+?)': (.+?)","errorType":"exception","errorClass":"ArgumentTypeError","httpStatus":null,"severity":"error","filePath":"Lib/argparse.py","lineNumber":1385,"sourceCode":"    def __call__(self, string):\n        # the special argument \"-\" means sys.std{in,out}\n        if string == '-':\n            if 'r' in self._mode:\n                return _sys.stdin.buffer if 'b' in self._mode else _sys.stdin\n            elif any(c in self._mode for c in 'wax'):\n                return _sys.stdout.buffer if 'b' in self._mode else _sys.stdout\n            else:\n                msg = _('argument \"-\" with mode %r') % self._mode\n                raise ValueError(msg)\n\n        # all other arguments are used as file names\n        try:\n            return open(string, self._mode, self._bufsize, self._encoding,\n                        self._errors)\n        except OSError as e:\n            args = {'filename': string, 'error': e}\n            message = _(\"can't open '%(filename)s': %(error)s\")\n            raise ArgumentTypeError(message % args)\n\n    def __repr__(self):\n        args = self._mode, self._bufsize\n        kwargs = [('encoding', self._encoding), ('errors', self._errors)]\n        args_str = ', '.join([repr(arg) for arg in args if arg != -1] +\n                             ['%s=%r' % (kw, arg) for kw, arg in kwargs\n                              if arg is not None])\n        return '%s(%s)' % (type(self).__name__, args_str)\n\n# ===========================\n# Optional and Positional Parsing\n# ===========================\n\nclass Namespace(_AttributeHolder):\n    \"\"\"Simple object for storing attributes.\n\n    Implements equality by attribute names and values, and provides a simple\n    string representation.","sourceCodeStart":1367,"sourceCodeEnd":1403,"githubUrl":"https://github.com/RustPython/RustPython/blob/aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd/Lib/argparse.py#L1367-L1403","documentation":"When the open() call inside FileType.__call__ raises OSError (missing file, missing directory, permission denied), the error is caught and re-raised as ArgumentTypeError carrying the path and the underlying message. parse_args turns this into a usage message on stderr and SystemExit with status 2, so the program stops before your code runs.","triggerScenarios":"add_argument('-i', type=argparse.FileType('r')) with a nonexistent path; FileType('w') where the parent directory does not exist or is not writable.","commonSituations":"Relative paths resolved from a different working directory (cron, systemd, containers); permission-denied on protected paths; paths coming from environment variables or upstream services.","solutions":["Pass a correct, existing (read modes) or writable (write modes) path; create parent directories first.","Use type=str plus your own open() later, wrapped in try/except, so the error is reportable.","Pre-validate known paths before parse_args and fail with your own message."],"exampleFix":"# before\nparser.add_argument('--out', type=argparse.FileType('w'))\n# after\nparser.add_argument('--out', type=str)\nargs = parser.parse_args()\nwith open(args.out, 'w') as out:\n    out.write(data)","handlingStrategy":"try-catch","validationCode":"def readable_file(path):\n    import os\n    if not os.path.isfile(path):\n        raise argparse.ArgumentTypeError('file not found: ' + path)\n    return path\n# use: parser.add_argument('-i', type=readable_file)","typeGuard":null,"tryCatchPattern":"# keep paths as strings at parse time; open later with explicit handling\ntry:\n    stream = open(args.out, 'w')\nexcept OSError as exc:\n    sys.exit('cannot open output file: ' + str(exc))","preventionTips":["Prefer type=str plus an explicit open in code you control; reserve FileType for quick tools.","Create parent directories with os.makedirs(..., exist_ok=True) before parse.","Resolve paths against an explicit base directory instead of the ambient working directory.","Catch SystemExit around parse_args in tests to assert the error message."],"tags":["argparse","filetype","file-not-found","permission-denied","argument-type-error"],"backgroundTag":"file-open-failed","analyzedSha":"aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd","analyzedAt":"2026-08-17T00:37:52.100Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}