{"record":{"id":"3560918cb8ea1db6","repo":"python/cpython","slug":"can-t-open-filename-s-error-s","errorCode":null,"errorMessage":"can't open '%(filename)s': %(error)s","messagePattern":"can't open '(.+?)': (.+?)","errorType":"validation","errorClass":"ArgumentTypeError","httpStatus":null,"severity":"error","filePath":"Lib/argparse.py","lineNumber":1515,"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":1497,"sourceCodeEnd":1533,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/argparse.py#L1497-L1533","documentation":"argparse.FileType.__call__ opens the given path with the configured mode/encoding; any OSError from open() (missing file, permission denied, IsADirectoryError) is wrapped in ArgumentTypeError with the filename and the underlying error. Note it is raised during parsing, so an unopenable file aborts argument parsing with argparse's standard error exit unless handled.","triggerScenarios":"add_argument('--out', type=argparse.FileType('w')) and passing a path in a non-existent directory; FileType('r') with a missing file; '-' with a bad mode combination; permission or encoding errors on the target file.","commonSituations":"Output paths whose parent directories do not exist; scripts run without read permission; users omitting an input file; UTF-8 files read with a non-UTF-8 locale encoding.","solutions":["Pre-create the output directory (e.g. Path(p).parent.mkdir(parents=True, exist_ok=True)) — FileType will not do it for you.","Verify the file exists/readability before parsing when a better error message matters: a custom type function that returns a path instead of an open file.","Replace FileType with type=str and open the file yourself in a try/except OSError, so you control the error handling and file lifetime."],"exampleFix":"# before\nparser.add_argument('--out', type=argparse.FileType('w'))\nparser.parse_args(['--out', 'newdir/out.txt'])  # ArgumentTypeError: can't open ... No such file or directory\n\n# after\nparser.add_argument('--out', type=str)\nargs = parser.parse_args()\nPath(args.out).parent.mkdir(parents=True, exist_ok=True)\nwith open(args.out, 'w') as f: ...","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\n\ndef input_file_ok(path: str) -> bool:\n    p = Path(path)\n    return p.is_file() and p.stat().st_size >= 0  # exists and readable-ish","typeGuard":null,"tryCatchPattern":"from argparse import ArgumentTypeError\n\ntry:\n    args = parser.parse_args()\nexcept (ArgumentTypeError, SystemExit) as e:\n    msg = str(e)\n    if \"can't open\" in msg:\n        # show a friendly message and create missing parent dirs if it was output\n        raise SystemExit(f'file error: {msg}')\n    raise","preventionTips":["Prefer type=str plus your own open() so you control OSError handling","Create output parent directories before parsing","Check input files exist before passing them to the CLI"],"tags":["python","argparse","cli","file-io","filetype","oserror"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}