os.path.normpath
normpath is pure string work: it never looks at the disk, so 'link/..' is removed even if link is a symlink pointing elsewhere. Leading '..' of a relative path are kept; on POSIX exactly two leading slashes are kept too. normcase is for comparisons: identity on POSIX, lower case with backslashes on Windows.
Demo
import posixpath posixpath.normpath('/usr//local/./bin/../lib/')
'bin/..' cancels out, '.' and the doubled and trailing slashes disappear. A relative path cannot go above its start, so normpath keeps the leading '..' parts; above the root there is nothing, so '/../etc' becomes '/etc'. An empty path becomes '.'. ntpath also turns every / into \. POSIX leaves exactly two leading slashes alone (their meaning is implementation-defined), while ntpath reads '//srv/x' as the UNC share \\srv\x.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| path | str | bytes | PathLike | yes | Any path. Nothing is checked on disk. |
Return value
str | bytes — The normalized path ('.' for an empty result).
Common patterns
import os same = os.path.normcase(os.path.normpath(a)) == os.path.normcase(os.path.normpath(b))
import os name = os.path.basename(os.path.normpath('/var/log/'))
import os canonical = os.path.realpath(path)
Examples
Pitfalls
import posixpath posixpath.normpath(posixpath.join('uploads', '../../etc/passwd'))
import posixpath base = '/srv/uploads' p = posixpath.normpath(posixpath.join(base, '../../etc/passwd')) posixpath.commonpath([base, p]) == base
import ntpath ntpath.normpath('C:/Data/A.txt') == ntpath.normpath(r'c:\data\a.txt')
import ntpath ntpath.normcase(ntpath.normpath('C:/Data/A.txt')) == ntpath.normcase(ntpath.normpath(r'c:\data\a.txt'))
When to use
- Displaying or comparing paths built by concatenation
- Removing trailing separators and redundant parts
- Resolving symlinks → os.path.realpath
- Making a path absolute → os.path.abspath (which calls normpath)
- Security checks on their own → combine with abspath + commonpath
Notes
FAQ
It rewrites a path string into a canonical form: A//B, A/B/, A/./B and A/foo/../B all become A/B. On Windows it also turns / into \. It does not access the file system.