os.fspath
os.fspath is the official way to say "give me this path as a string": str and bytes pass through, Path objects (and anything with __fspath__) are converted, everything else is a TypeError. fsencode and fsdecode translate between str and bytes names using the encoding the OS calls expect.
Demo
import os raw = os.fsencode('report.txt') (raw, os.fsdecode(raw))
fsencode uses UTF-8 here (the file system encoding on Windows and on any modern Linux or macOS), so é becomes b'\xc3\xa9' and the CJK characters three bytes each; fsdecode reverses it exactly. In the fspath tab the str is returned as typed, while the Path object has already dropped the doubled slash, the '.' and the trailing slash — and an empty path becomes '.'.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| path / filename | str | bytes | os.PathLike | yes | A path in any accepted form. fsencode returns bytes unchanged; fsdecode returns str unchanged. |
Return value
str | bytes — fspath: str or bytes unchanged, otherwise the result of __fspath__(). fsencode: bytes. fsdecode: str.
Common patterns
import os def load(path): path = os.fspath(path) # str, bytes, Path, DirEntry … all fine with open(path, 'rb') as f: return f.read()
import os class Asset: def __init__(self, root, name): self.root, self.name = root, name def __fspath__(self): return os.path.join(self.root, self.name)
import os raw_name = os.fsencode(filename)
Examples
Pitfalls
path = None str(path)
import os path = None os.fspath(path)
import os class Bad: def __fspath__(self): return 42 os.fspath(Bad())
import os class Good: def __fspath__(self): return 'file42.txt' os.fspath(Good())
When to use
- Functions that accept "any path" and need a str or bytes
- Talking to APIs that want bytes file names (fsencode) or produced them (fsdecode)
- Displaying a path to a user → str(path) is fine there
- Decoding file contents → bytes.decode with the content encoding, not fsdecode
Notes
FAQ
os.fspath(p) or str(p) — both give the same string for a Path. Prefer os.fspath in code that should reject non-paths: str() converts anything, including None.