os.remove
remove and unlink are the same operation: delete one file (never a folder). For renaming, prefer os.replace: it overwrites an existing destination on Linux, macOS and Windows alike, and is atomic on POSIX when both paths are on the same file system. os.rename overwrites on POSIX but raises FileExistsError on Windows.
Demo
import os for f in ['a.log', 'b.log', 'keep.txt']: os.makedirs(os.path.dirname(f) or '.', exist_ok=True) open(f, 'w').close() try: os.remove('a.log') result = sorted(os.listdir('.')) except OSError as e: result = type(e).__name__ result
A missing file raises FileNotFoundError on every OS. replace overwrote data.json — the listing shows one file whose content is now 'new.json'. Moving into archive/ works because the folder exists. renames made final/2026, moved the file, and removed tmp/a and tmp because they became empty. Not shown, because the result depends on the OS: os.remove on a folder raises IsADirectoryError on Linux and PermissionError on Windows, and os.rename onto an existing file replaces it on POSIX but raises FileExistsError on Windows.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| path / src | str | PathLike | yes | The file to delete, or the file or folder to rename. |
| dst | str | PathLike | yes | The new name. Its folder must exist (except with renames, which creates it). Moving across file systems fails — use shutil.move. |
Return value
None — They change the file system and return None, or raise an OSError subclass.
Common patterns
import os tmp = path + '.tmp' with open(tmp, 'w', encoding='utf-8') as f: f.write(text) f.flush() os.fsync(f.fileno()) os.replace(tmp, path)
import contextlib, os with contextlib.suppress(FileNotFoundError): os.remove('cache.db')
import os for name in os.listdir('.'): root, ext = os.path.splitext(name) if ext == '.jpeg': os.replace(name, root + '.jpg')
import shutil shutil.move('/tmp/upload.bin', '/data/upload.bin')
Examples
Pitfalls
import os for n in ['new.txt', 'old.txt']: with open(n, 'w') as f: f.write(n) try: os.rename('new.txt', 'old.txt') outcome = 'replaced' except FileExistsError: outcome = 'FileExistsError' outcome == ('FileExistsError' if os.name == 'nt' else 'replaced')
import os for n in ['new.txt', 'old.txt']: with open(n, 'w') as f: f.write(n) os.replace('new.txt', 'old.txt') sorted(os.listdir('.'))
import os os.mkdir('d') try: os.remove('d') failed = False except OSError: failed = True failed
import os os.mkdir('d') os.rmdir('d') os.listdir('.')
import os for n in ['cfg.new', 'cfg']: open(n, 'w').close() os.remove('cfg') os.rename('cfg.new', 'cfg') os.listdir('.')
import os for n in ['cfg.new', 'cfg']: open(n, 'w').close() os.replace('cfg.new', 'cfg') os.listdir('.')
When to use
- Deleting single files (remove)
- Renaming or moving within one file system (replace — or rename when the target never exists)
- Publishing a finished file atomically (write a temp file, then replace)
- Folders → os.rmdir (empty) or shutil.rmtree (full)
- Moving between disks → shutil.move
- Copying → shutil.copy2 / copyfile
Notes
FAQ
os.remove('file.txt') (or Path('file.txt').unlink()). It raises FileNotFoundError if the file is missing — wrap it in contextlib.suppress(FileNotFoundError) to ignore that.