os.path.relpath
relpath makes both arguments absolute (with abspath, so relative ones depend on the current directory), drops their common leading folders and climbs out of the rest of start with '..'. It never looks at the file system, so it cannot know whether start is a file or a folder — start is always treated as a folder.
Demo
import posixpath cwd = '/home/ada/project' # stands in for os.getcwd() posixpath.relpath(posixpath.join(cwd, '/srv/app/static/css/site.css'), posixpath.join(cwd, '/srv/app'))
From /srv/app/static, /srv/data is two levels up and one down: '../../data'. A trailing slash on start makes no difference, and identical locations give '.'. With relative inputs both are first placed under the same current directory, so the result does not depend on what that directory is — unless '..' climbs above it.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| path | str | bytes | PathLike | yes | The target. Must not be empty (ValueError: no path specified). |
| start | str | bytes | PathLike | no (os.curdir) | The folder to be relative to. A file name here is treated as a folder too. |
Return value
str | bytes — A relative path from start to path; '.' when they are the same.
Common patterns
import os for root, dirs, files in os.walk(PROJECT): for name in files: print(os.path.relpath(os.path.join(root, name), PROJECT))
import os arcname = os.path.relpath(full_path, src_dir).replace(os.sep, '/')
import os try: shown = os.path.relpath(path, base) except ValueError: shown = path
Examples
Pitfalls
base = '/srv/app' path = '/srv/app2/x.txt' path[len(base) + 1:]
import posixpath posixpath.relpath('/srv/app2/x.txt', '/srv/app')
import posixpath posixpath.relpath('/site/img/a.png', '/site/pages/about.html')
import posixpath posixpath.relpath('/site/img/a.png', posixpath.dirname('/site/pages/about.html'))
When to use
- Displaying paths relative to a base folder
- Building relative links between files (HTML, Markdown, symlinks)
- pathlib code → PurePath.relative_to(other, walk_up=True) (3.12+)
- Checking whether a path is inside a folder → commonpath
Notes
FAQ
os.path.relpath(path, base). With pathlib: Path(path).relative_to(base) — which raises ValueError unless path is inside base, or pass walk_up=True (3.12+) to allow '..'.