{"record":{"id":"5a81dee2100dcba2","repo":"python/cpython","slug":"invalid-file-r","errorCode":null,"errorMessage":"invalid file: %r","messagePattern":"invalid file: %r","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"Lib/_pyio.py","lineNumber":197,"sourceCode":"\n    open() returns a file object whose type depends on the mode, and\n    through which the standard file operations such as reading and writing\n    are performed. When open() is used to open a file in a text mode ('w',\n    'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open\n    a file in a binary mode, the returned class varies: in read binary\n    mode, it returns a BufferedReader; in write binary and append binary\n    modes, it returns a BufferedWriter, and in read/write mode, it returns\n    a BufferedRandom.\n\n    It is also possible to use a string or bytearray as a file for both\n    reading and writing. For strings StringIO can be used like a file\n    opened in a text mode, and for bytes a BytesIO can be used like a file\n    opened in a binary mode.\n    \"\"\"\n    if not isinstance(file, int):\n        file = os.fspath(file)\n    if not isinstance(file, (str, bytes, int)):\n        raise TypeError(\"invalid file: %r\" % file)\n    if not isinstance(mode, str):\n        raise TypeError(\"invalid mode: %r\" % mode)\n    if not isinstance(buffering, int):\n        raise TypeError(\"invalid buffering: %r\" % buffering)\n    if encoding is not None and not isinstance(encoding, str):\n        raise TypeError(\"invalid encoding: %r\" % encoding)\n    if errors is not None and not isinstance(errors, str):\n        raise TypeError(\"invalid errors: %r\" % errors)\n    modes = set(mode)\n    if modes - set(\"axrwb+t\") or len(mode) > len(modes):\n        raise ValueError(\"invalid mode: %r\" % mode)\n    creating = \"x\" in modes\n    reading = \"r\" in modes\n    writing = \"w\" in modes\n    appending = \"a\" in modes\n    updating = \"+\" in modes\n    text = \"t\" in modes\n    binary = \"b\" in modes","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyio.py#L179-L215","documentation":"Raised by io.open() (the _pyio reference implementation of builtins.open) when the file argument cannot be reduced to a path or file descriptor. open() first passes file through os.fspath(); if the result is not str, bytes, or an int (fd number), this TypeError is raised. It is a type-validation error at the API boundary, before any filesystem access happens.","triggerScenarios":"open(None), open(['a.txt']), open({'path': 'a.txt'}), or an os.PathLike class whose __fspath__ returns a non-str/bytes value (e.g. returns None or an int). Also passing a closed/garbage object where a path was expected, e.g. open(some_result) where some_result is None because a lookup failed.","commonSituations":"A variable expected to hold a filename is None because an earlier config lookup, argparse default, or function return was missed; passing a list of paths to open() instead of looping; custom PathLike wrappers (mocks in tests, lazy-path objects) whose __fspath__ has the wrong return type.","solutions":["Check where the value came from: it is None or a container, not a path — fix the upstream assignment (config key, argparse argument, function return).","Pass a str, bytes, os.PathLike (e.g. pathlib.Path), or an int file descriptor to open().","If you wrote the custom class being passed, make its __fspath__ return str or bytes.","Loop over path collections: for p in paths: with open(p) as f: ... instead of open(paths)."],"exampleFix":"// before\npath = config.get('logfile')  # returns None when key missing\nf = open(path)  # TypeError: invalid file: None\n\n// after\npath = config['logfile']  # fail fast on missing key, or:\nif not isinstance(path, (str, bytes, os.PathLike)):\n    raise TypeError(f'expected a path, got {path!r}')\nf = open(path)","handlingStrategy":"type-guard","validationCode":"import os\n\ndef validate_path(file):\n    if isinstance(file, int):\n        return file          # file descriptor\n    p = os.fspath(file) if isinstance(file, os.PathLike) else file\n    if not isinstance(p, (str, bytes)):\n        raise TypeError(f'path must be str/bytes/PathLike/fd, got {type(file).__name__}')\n    return p","typeGuard":"import os\n\ndef is_openable(file) -> bool:\n    if isinstance(file, int):\n        return True\n    try:\n        p = os.fspath(file)\n    except TypeError:\n        return False\n    return isinstance(p, (str, bytes))","tryCatchPattern":"try:\n    f = open(target)\nexcept TypeError as e:\n    # 'invalid file' — target was None/list/etc.\n    raise ValueError(f'bad path from config: {target!r}') from None","preventionTips":["Fail fast on config/argparse lookups so path variables are never None (use [] with defaults, not .get).","Type-annotate path parameters as str | os.PathLike and check at boundaries.","Loop over collections of paths; never pass a list/dict where one path is expected."],"tags":["io","file","open","typeerror","path"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}