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.

pathlib classPython 3.4+
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

NameTypeRequiredDescription
*pathsegmentsstr | os.PathLikeno ('.')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
True
6. 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
True

Pitfalls

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.