pathlib.PureWindowsPath
Parse, join and compare Windows paths the way Windows does — on Linux and macOS too. Both "\" and "/" separate; a drive plus a root makes a path absolute; case is ignored when comparing.
Common call
PureWindowsPath(r'C:\Users\ada\notes.txt')
Returns
PureWindowsPath('C:/Users/ada/notes.txt') — repr always uses /
Replaces
ntpath.join / ntpath.splitdrive on strings
Watch out
'/foo' and 'C:foo' are NOT absolute on Windows
pathlib.PureWindowsPath(*pathsegments)
→ PureWindowsPath
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| *pathsegments | str | os.PathLike | no ('.') | Segments joined with Windows rules: a new drive replaces everything; a new root keeps the current drive. |
Return value
PureWindowsPath — A pure path with Windows semantics.
Common patterns
Convert a Windows path to forward slashes
as_posix() is the portable way to show or store it.
from pathlib import PureWindowsPath PureWindowsPath(r'C:\data\in.csv').as_posix() # 'C:/data/in.csv'
Case-insensitive lookups
Equality and hashing ignore case, so a set of PureWindowsPath de-duplicates like Windows does.
from pathlib import PureWindowsPath files = {PureWindowsPath(p) for p in ['C:/A.TXT', 'c:/a.txt']} len(files) # 1
Handle paths from a Windows config on a Linux server
Parse with Windows rules, then keep only the parts you need.
from pathlib import PurePosixPath, PureWindowsPath win = PureWindowsPath(config['share_path']) local = PurePosixPath('/mnt/share', *win.parts[1:])
Examples
1. Backslashes and slashes both separate
from pathlib import PureWindowsPath
PureWindowsPath('C:/Users\\ada\\notes.txt')
Returns
PureWindowsPath('C:/Users/ada/notes.txt')2. str() uses backslashes
from pathlib import PureWindowsPath
str(PureWindowsPath('C:/Users/ada'))
Returns
'C:\\Users\\ada'3. drive, root, anchor
from pathlib import PureWindowsPath
p = PureWindowsPath('C:/Users')
(p.drive, p.root, p.anchor)
Returns
('C:', '\\', 'C:\\')4. A UNC share is one drive
from pathlib import PureWindowsPath
PureWindowsPath('//server/share/q3.xlsx').drive
Returns
'\\\\server\\share'5. Comparison ignores case
from pathlib import PureWindowsPath
PureWindowsPath('C:/A.TXT') == PureWindowsPath('c:/a.txt')
Returns
True6. A new drive replaces the path; a new root keeps the drive
from pathlib import PureWindowsPath
(PureWindowsPath('C:/a') / 'D:/b', PureWindowsPath('C:/a') / '/b')
Returns
(PureWindowsPath('D:/b'), PureWindowsPath('C:/b'))7. Reserved device names (deprecated check)
import warnings
from pathlib import PureWindowsPath
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
reserved = PureWindowsPath('nul').is_reserved()
reserved
Returns
TruePitfalls
1. Thinking "/foo" is absolute on Windows
Windows needs both a drive and a root. "/foo" is relative to the current drive, "C:foo" to the current directory of drive C.
root only
from pathlib import PureWindowsPath PureWindowsPath('/foo').is_absolute()
False
drive + root
from pathlib import PureWindowsPath PureWindowsPath('C:/foo').is_absolute()
True
2. Parsing a Windows path with the POSIX flavour
On Linux and macOS, Path and PurePosixPath treat "\" as an ordinary character — the whole string becomes one part.
PurePosixPath
from pathlib import PurePosixPath PurePosixPath('C:\\data\\in.csv').name
'C:\\data\\in.csv'
PureWindowsPath
from pathlib import PureWindowsPath PureWindowsPath('C:\\data\\in.csv').name
'in.csv'
3. Matching patterns case-sensitively by accident
match() and full_match() follow the flavour: case-insensitive on PureWindowsPath, case-sensitive on PurePosixPath. Pass case_sensitive= to force either.
posix default
from pathlib import PurePosixPath PurePosixPath('/x/REPORT.PDF').match('*.pdf')
False
case_sensitive=False
from pathlib import PurePosixPath PurePosixPath('/x/REPORT.PDF').match('*.pdf', case_sensitive=False)
True
When to use
Use it
- Reading Windows paths from configs, logs or databases on any OS
- Tests of Windows path handling that must run on Linux CI
Reach for something else
- Real file access on Windows → Path (it is a WindowsPath there)
- Normalising case or ".." → only resolve() on the real machine can do that reliably
Notes
CPython impl
PurePath with parser = ntpath (Lib/ntpath.py: splitroot, join, normcase)
repr vs str
repr() shows forward slashes; str() shows backslashes
is_reserved()
Deprecated since 3.13, removed in 3.15 — use os.path.isreserved() (Windows) instead; always False for POSIX paths
Absolute
Needs a drive AND a root: C:\x or \\server\share\x
FAQ
Use PureWindowsPath: it understands drive letters, backslashes and UNC shares on any OS. PureWindowsPath(r'C:\data\in.csv').name is 'in.csv' even on Linux.