Path.resolve

resolve() = os.path.realpath: absolute, '..' collapsed, symlinks followed. absolute() = cwd / path, nothing else — '..' stays. expanduser() only touches a leading '~'. The results depend on the machine, so this page has no live demo; the examples compare paths instead of printing them.

pathlib methodPython 3.4+ (home, expanduser 3.5+)
Common call
Path(__file__).resolve().parent
Returns
an absolute Path
Replaces
os.path.realpath / abspath / expanduser, os.getcwd()
Watch out
absolute() keeps '..'; resolve() does not require the path to exist unless strict=True
Path.resolve(strictstrict — resolve only: raise OSError (FileNotFoundError) if a component does not exist, instead of resolving as far as possible.type: bool · default: False=False) / .absolute() / .expanduser() / Path.cwd() / Path.home()
→ Path

Parameters

NameTypeRequiredDescription
strictboolno (False)resolve only: raise OSError (FileNotFoundError) if a component does not exist, instead of resolving as far as possible.

Return value

Path — A new absolute (resolve, absolute, cwd, home) or tilde-free (expanduser) path.

Common patterns

The folder of the running script
resolve() makes it absolute and follows a symlinked script.
from pathlib import Path
HERE = Path(__file__).resolve().parent
User-configurable paths
Expand ~ first, then make absolute.
from pathlib import Path
data_dir = Path(config.get('data_dir', '~/.myapp')).expanduser().resolve()
Per-user config folder
home() is the user profile / home directory.
from pathlib import Path
config = Path.home() / '.config' / 'myapp' / 'settings.toml'

Examples

1. resolve() is absolute
from pathlib import Path Path('data.csv').resolve().is_absolute()
Returns
True
2. resolve() removes '..'
from pathlib import Path Path('src').mkdir() '..' in Path('src/../data.csv').resolve().parts
Returns
False
3. absolute() keeps '..'
from pathlib import Path '..' in Path('src/../data.csv').absolute().parts
Returns
True
4. absolute() is cwd / path
from pathlib import Path Path('a/b').absolute() == Path.cwd() / 'a' / 'b'
Returns
True
5. expanduser() replaces a leading ~
from pathlib import Path Path('~/notes.txt').expanduser() == Path.home() / 'notes.txt'
Returns
True
6. expanduser() leaves other paths alone
from pathlib import Path Path('a/~/b').expanduser().as_posix()
Returns
'a/~/b'
7. strict=True needs an existing path
from pathlib import Path try: Path('missing.txt').resolve(strict=True) except OSError as e: result = type(e).__name__ result
Returns
'FileNotFoundError'

Pitfalls

1. Expecting absolute() to clean up '..'
absolute() only prefixes the cwd; the '..' stays. Use resolve() when you need the canonical path (for comparisons or containment checks).
absolute()
from pathlib import Path
Path('a').mkdir()
Path('a/../b').absolute() == Path('b').absolute()
False
resolve()
from pathlib import Path
Path('a').mkdir()
Path('a/../b').resolve() == Path('b').resolve()
True
2. Opening "~/file" without expanduser()
The OS does not expand '~'; only shells do. Python looks for a folder literally named ~ in the current directory.
raw '~'
from pathlib import Path
Path('~/definitely-missing-file.txt').exists()
False
expanduser()
from pathlib import Path
Path('~/x').expanduser().is_absolute()
True

When to use

Use it
  • resolve(): canonical paths for comparison, containment checks, anchoring to __file__
  • absolute(): cheap absolute path without file-system access or symlink resolution
  • expanduser(): paths from users and config files that may start with ~
Reach for something else
  • Pure paths → none of these exist on PurePath; they need the machine's cwd and home
  • Keeping symlinks as they are → absolute() rather than resolve()

Notes

CPython impl
resolve: self.with_segments(os.path.realpath(self, strict=strict)); absolute: joins os.getcwd() with the parsed parts without normalising; expanduser: os.path.expanduser on the first part
os.path table
os.path.realpath → resolve(); os.path.abspath → absolute() (but abspath DOES collapse "..", absolute() does not); os.path.expanduser → expanduser(); os.getcwd → Path.cwd()
expanduser errors
RuntimeError("Could not determine home directory.") when the home directory cannot be found — os.path.expanduser returns the path unchanged instead
Changed in 3.13
Symlink loops no longer raise RuntimeError: OSError in strict mode, no error otherwise
Inherited
cwd() and home() are class methods inherited from PathBase; cwd() == Path().absolute()

FAQ

absolute() prefixes the current directory and does nothing else. resolve() also collapses '..' and follows symlinks, like os.path.realpath. Use resolve() for comparisons; absolute() when you must not follow links.