:mod:`!pathlib` --- Object-oriented filesystem paths
====================================================

.. module:: pathlib
   :synopsis: Object-oriented filesystem paths

.. versionadded:: 3.4

**Source code:** :source:`Lib/pathlib/`

.. index:: single: path; operations

--------------

This module offers classes representing filesystem paths with semantics
appropriate for different operating systems.  Path classes are divided
between :ref:`pure paths <pure-paths>`, which provide purely computational
operations without I/O, and :ref:`concrete paths <concrete-paths>`, which
inherit from pure paths but also provide I/O operations.

.. image:: pathlib-inheritance.png
   :align: center
   :class: invert-in-dark-mode
   :alt: Inheritance diagram showing the classes available in pathlib. The
         most basic class is PurePath, which has three direct subclasses:
         PurePosixPath, PureWindowsPath, and Path. Further to these four
         classes, there are two classes that use multiple inheritance:
         PosixPath subclasses PurePosixPath and Path, and WindowsPath
         subclasses PureWindowsPath and Path.

If you've never used this module before or just aren't sure which class is
right for your task, :class:`Path` is most likely what you need. It instantiates
a :ref:`concrete path <concrete-paths>` for the platform the code is running on.

Pure paths are useful in some special cases; for example:

#. If you want to manipulate Windows paths on a Unix machine (or vice versa).
   You cannot instantiate a :class:`WindowsPath` when running on Unix, but you
   can instantiate :class:`PureWindowsPath`.
#. You want to make sure that your code only manipulates paths without actually
   accessing the OS. In this case, instantiating one of the pure classes may be
   useful since those simply don't have any OS-accessing operations.

.. seealso::
   :pep:`428`: The pathlib module -- object-oriented filesystem paths.

.. seealso::
   For low-level path manipulation on strings, you can also use the
   :mod:`os.path` module.


Basic use
---------

Importing the main class::

   >>> from pathlib import Path

Listing subdirectories::

   >>> p = Path('.')
   >>> [x for x in p.iterdir() if x.is_dir()]
   [PosixPath('.hg'), PosixPath('docs'), PosixPath('dist'),
    PosixPath('__pycache__'), PosixPath('build')]

Listing Python source files in this directory tree::

   >>> list(p.glob('**/*.py'))
   [PosixPath('test_pathlib.py'), PosixPath('setup.py'),
    PosixPath('pathlib.py'), PosixPath('docs/conf.py'),
    PosixPath('build/lib/pathlib.py')]

Navigating inside a directory tree::

   >>> p = Path('/etc')
   >>> q = p / 'init.d' / 'reboot'
   >>> q
   PosixPath('/etc/init.d/reboot')
   >>> q.resolve()
   PosixPath('/etc/rc.d/init.d/halt')

Querying path properties::

   >>> q.exists()
   True
   >>> q.is_dir()
   False

Opening a file::

   >>> with q.open() as f: f.readline()
   ...
   '#!/bin/bash\n'


Exceptions
----------

.. exception:: UnsupportedOperation

   An exception inheriting :exc:`NotImplementedError` that is raised when an
   unsupported operation is called on a path object.

   .. versionadded:: 3.13


.. _pure-paths:

Pure paths
----------

Pure path objects provide path-handling operations which don't actually
access a filesystem.  There are three ways to access these classes, which
we also call *flavours*:

.. class:: PurePath(*pathsegments)

   A generic class that represents the system's path flavour (instantiating
   it creates either a :class:`PurePosixPath` or a :class:`PureWindowsPath`)::

      >>> PurePath('setup.py')      # Running on a Unix machine
      PurePosixPath('setup.py')

   Each element of *pathsegments* can be either a string representing a
   path segment, or an object implementing the :class:`os.PathLike` interface
   where the :meth:`~os.PathLike.__fspath__` method returns a string,
   such as another path object::

      >>> PurePath('foo', 'some/path', 'bar')
      PurePosixPath('foo/some/path/bar')
      >>> PurePath(Path('foo'), Path('bar'))
      PurePosixPath('foo/bar')

   When *pathsegments* is empty, the current directory is assumed::

      >>> PurePath()
      PurePosixPath('.')

   If a segment is an absolute path, all previous segments are ignored
   (like :func:`os.path.join`)::

      >>> PurePath('/etc', '/usr', 'lib64')
      PurePosixPath('/usr/lib64')
      >>> PureWindowsPath('c:/Windows', 'd:bar')
      PureWindowsPath('d:bar')

   On Windows, the drive is not reset when a rooted relative path
   segment (e.g., ``r'\foo'``) is encountered::

      >>> PureWindowsPath('c:/Windows', '/Program Files')
      PureWindowsPath('c:/Program Files')

   Spurious slashes and single dots are collapsed, but double dots (``'..'``)
   and leading double slashes (``'//'``) are not, since this would change the
   meaning of a path for various reasons (e.g. symbolic links, UNC paths)::

      >>> PurePath('foo//bar')
      PurePosixPath('foo/bar')
      >>> PurePath('//foo/bar')
      PurePosixPath('//foo/bar')
      >>> PurePath('foo/./bar')
      PurePosixPath('foo/bar')
      >>> PurePath('foo/../bar')
      PurePosixPath('foo/../bar')

   (a naïve approach would make ``PurePosixPath('foo/../bar')`` equivalent
   to ``PurePosixPath('bar')``, which is wrong if ``foo`` is a symbolic link
   to another directory)

   Pure path objects implement the :class:`os.PathLike` interface, allowing them
   to be used anywhere the interface is accepted.

   .. versionchanged:: 3.6
      Added support for the :class:`os.PathLike` interface.

.. class:: PurePosixPath(*pathsegments)

   A subclass of :class:`PurePath`, this path flavour represents non-Windows
   filesystem paths::

      >>> PurePosixPath('/etc/hosts')
      PurePosixPath('/etc/hosts')

   *pathsegments* is specified similarly to :class:`PurePath`.

.. class:: PureWindowsPath(*pathsegments)

   A subclass of :class:`PurePath`, this path flavour represents Windows
   filesystem paths, including `UNC paths`_::

      >>> PureWindowsPath('c:/', 'Users', 'Ximénez')
      PureWindowsPath('c:/Users/Ximénez')
      >>> PureWindowsPath('//server/share/file')
      PureWindowsPath('//server/share/file')

   *pathsegments* is specified similarly to :class:`PurePath`.

   .. _unc paths: https://en.wikipedia.org/wiki/Path_(computing)#UNC

Regardless of the system you're running on, you can instantiate all of
these classes, since they don't provide any operation that does system calls.


General properties
^^^^^^^^^^^^^^^^^^

Paths are immutable and :term:`hashable`.  Paths of a same flavour are comparable
and orderable.  These properties respect the flavour's case-folding
semantics::

   >>> PurePosixPath('foo') == PurePosixPath('FOO')
   False
   >>> PureWindowsPath('foo') == PureWindowsPath('FOO')
   True
   >>> PureWindowsPath('FOO') in { PureWindowsPath('foo') }
   True
   >>> PureWindowsPath('C:') < PureWindowsPath('d:')
   True

Paths of a different flavour compare unequal and cannot be ordered::

   >>> PureWindowsPath('foo') == PurePosixPath('foo')
   False
   >>> PureWindowsPath('foo') < PurePosixPath('foo')
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: '<' not supported between instances of 'PureWindowsPath' and 'PurePosixPath'


Operators
^^^^^^^^^

The slash operator helps create child paths, like :func:`os.path.join`.
If the argument is an absolute path, the previous path is ignored.
On Windows, the drive is not reset when the argument is a rooted
relative path (e.g., ``r'\foo'``)::

   >>> p = PurePath('/etc')
   >>> p
   PurePosixPath('/etc')
   >>> p / 'init.d' / 'apache2'
   PurePosixPath('/etc/init.d/apache2')
   >>> q = PurePath('bin')
   >>> '/usr' / q
   PurePosixPath('/usr/bin')
   >>> p / '/an_absolute_path'
   PurePosixPath('/an_absolute_path')
   >>> PureWindowsPath('c:/Windows', '/Program Files')
   PureWindowsPath('c:/Program Files')

A path object can be used anywhere an object implementing :class:`os.PathLike`
is accepted::

   >>> import os
   >>> p = PurePath('/etc')
   >>> os.fspath(p)
   '/etc'

The string representation of a path is the raw filesystem path itself
(in native form, e.g. with backslashes under Windows), which you can
pass to any function taking a file path as a string::

   >>> p = PurePath('/etc')
   >>> str(p)
   '/etc'
   >>> p = PureWindowsPath('c:/Program Files')
   >>> str(p)
   'c:\\Program Files'

Similarly, calling :class:`bytes` on a path gives the raw filesystem path as a
bytes object, as encoded by :func:`os.fsencode`::

   >>> bytes(p)
   b'/etc'

.. note::
   Calling :class:`bytes` is only recommended under Unix.  Under Windows,
   the unicode form is the canonical representation of filesystem paths.


Accessing individual parts
^^^^^^^^^^^^^^^^^^^^^^^^^^

To access the individual "parts" (components) of a path, use the following
property:

.. attribute:: PurePath.parts

   A tuple giving access to the path's various components::

      >>> p = PurePath('/usr/bin/python3')
      >>> p.parts
      ('/', 'usr', 'bin', 'python3')

      >>> p = PureWindowsPath('c:/Program Files/PSF')
      >>> p.parts
      ('c:\\', 'Program Files', 'PSF')

   (note how the drive and local root are regrouped in a single part)


Methods and properties
^^^^^^^^^^^^^^^^^^^^^^

.. testsetup::

   from pathlib import PurePath, PurePosixPath, PureWindowsPath

Pure paths provide the following methods and properties:

.. attribute:: PurePath.parser

   The implementation of the :mod:`os.path` module used for low-level path
   parsing and joining: either :mod:`!posixpath` or :mod:`!ntpath`.

   .. versionadded:: 3.13

.. attribute:: PurePath.drive

   A string representing the drive letter or name, if any::

      >>> PureWindowsPath('c:/Program Files/').drive
      'c:'
      >>> PureWindowsPath('/Program Files/').drive
      ''
      >>> PurePosixPath('/etc').drive
      ''

   UNC shares are also considered drives::

      >>> PureWindowsPath('//host/share/foo.txt').drive
      '\\\\host\\share'

.. attribute:: PurePath.root

   A string representing the (local or global) root, if any::

      >>> PureWindowsPath('c:/Program Files/').root
      '\\'
      >>> PureWindowsPath('c:Program Files/').root
      ''
      >>> PurePosixPath('/etc').root
      '/'

   UNC shares always have a root::

      >>> PureWindowsPath('//host/share').root
      '\\'

   If the path starts with more than two successive slashes,
   :class:`~pathlib.PurePosixPath` collapses them::

      >>> PurePosixPath('//etc').root
      '//'
      >>> PurePosixPath('///etc').root
      '/'
      >>> PurePosixPath('////etc').root
      '/'

   .. note::

      This behavior conforms to *The Open Group Base Specifications Issue 6*,
      paragraph `4.11 Pathname Resolution
      <https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11>`_:

      *"A pathname that begins with two successive slashes may be interpreted in
      an implementation-defined manner, although more than two leading slashes
      shall be treated as a single slash."*

.. attribute:: PurePath.anchor

   The concatenation of the drive and root::

      >>> PureWindowsPath('c:/Program Files/').anchor
      'c:\\'
      >>> PureWindowsPath('c:Program Files/').anchor
      'c:'
      >>> PurePosixPath('/etc').anchor
      '/'
      >>> PureWindowsPath('//host/share').anchor
      '\\\\host\\share\\'


.. attribute:: PurePath.parents

   An immutable sequence providing access to the logical ancestors of
   the path::

      >>> p = PureWindowsPath('c:/foo/bar/setup.py')
      >>> p.parents[0]
      PureWindowsPath('c:/foo/bar')
      >>> p.parents[1]
      PureWindowsPath('c:/foo')
      >>> p.parents[2]
      PureWindowsPath('c:/')

   .. versionchanged:: 3.10
      The parents sequence now supports :term:`slices <slice>` and negative index values.

.. attribute:: PurePath.parent

   The logical parent of the path::

      >>> p = PurePosixPath('/a/b/c/d')
      >>> p.parent
      PurePosixPath('/a/b/c')

   You cannot go past an anchor, or empty path::

      >>> p = PurePosixPath('/')
      >>> p.parent
      PurePosixPath('/')
      >>> p = PurePosixPath('.')
      >>> p.parent
      PurePosixPath('.')

   .. note::
      This is a purely lexical operation, hence the following behaviour::

         >>> p = PurePosixPath('foo/..')
         >>> p.parent
         PurePosixPath('foo')

      If you want to walk an arbitrary filesystem path upwards, it is
      recommended to first call :meth:`Path.resolve` so as to resolve
      symlinks and eliminate ``".."`` components.


.. attribute:: PurePath.name

   A string representing the final path component, excluding the drive and
   root, if any::

      >>> PurePosixPath('my/library/setup.py').name
      'setup.py'

   UNC drive names are not considered::

      >>> PureWindowsPath('//some/share/setup.py').name
      'setup.py'
      >>> PureWindowsPath('//some/share').name
      ''


.. attribute:: PurePath.suffix

   The last dot-separated portion of the final component, if any::

      >>> PurePosixPath('my/library/setup.py').suffix
      '.py'
      >>> PurePosixPath('my/library.tar.gz').suffix
      '.gz'
      >>> PurePosixPath('my/library').suffix
      ''

   This is commonly called the file extension.

   .. versionchanged:: 3.14

      A single dot ("``.``") is considered a valid suffix.

.. attribute:: PurePath.suffixes

   A list of the path's suffixes, often called file extensions::

      >>> PurePosixPath('my/library.tar.gar').suffixes
      ['.tar', '.gar']
      >>> PurePosixPath('my/library.tar.gz').suffixes
      ['.tar', '.gz']
      >>> PurePosixPath('my/library').suffixes
      []

   .. versionchanged:: 3.14

      A single dot ("``.``") is considered a valid suffix.


.. attribute:: PurePath.stem

   The final path component, without its suffix::

      >>> PurePosixPath('my/library.tar.gz').stem
      'library.tar'
      >>> PurePosixPath('my/library.tar').stem
      'library'
      >>> PurePosixPath('my/library').stem
      'library'


.. method:: PurePath.as_posix()

   Return a string representation of the path with forward slashes (``/``)::

      >>> p = PureWindowsPath('c:\\windows')
      >>> str(p)
      'c:\\windows'
      >>> p.as_posix()
      'c:/windows'


.. method:: PurePath.is_absolute()

   Return whether the path is absolute or not.  A path is considered absolute
   if it has both a root and (if the flavour allows) a drive::

      >>> PurePosixPath('/a/b').is_absolute()
      True
      >>> PurePosixPath('a/b').is_absolute()
      False

      >>> PureWindowsPath('c:/a/b').is_absolute()
      True
      >>> PureWindowsPath('/a/b').is_absolute()
      False
      >>> PureWindowsPath('c:').is_absolute()
      False
      >>> PureWindowsPath('//some/share').is_absolute()
      True


.. method:: PurePath.is_relative_to(other)

   Return whether or not this path is relative to the *other* path.

      >>> p = PurePath('/etc/passwd')
      >>> p.is_relative_to('/etc')
      True
      >>> p.is_relative_to('/usr')
      False

   This method is string-based; it neither accesses the filesystem nor treats
   "``..``" segments specially. The following code is equivalent:

      >>> u = PurePath('/usr')
      >>> u == p or u in p.parents
      False

   .. versionadded:: 3.9

   .. deprecated-removed:: 3.12 3.14

      Passing additional arguments is deprecated; if supplied, they are joined
      with *other*.

.. method:: PurePath.joinpath(*pathsegments)

   Calling this method is equivalent to combining the path with each of
   the given *pathsegments* in turn::

      >>> PurePosixPath('/etc').joinpath('passwd')
      PurePosixPath('/etc/passwd')
      >>> PurePosixPath('/etc').joinpath(PurePosixPath('passwd'))
      PurePosixPath('/etc/passwd')
      >>> PurePosixPath('/etc').joinpath('init.d', 'apache2')
      PurePosixPath('/etc/init.d/apache2')
      >>> PureWindowsPath('c:').joinpath('/Program Files')
      PureWindowsPath('c:/Program Files')


.. method:: PurePath.full_match(pattern, *, case_sensitive=None)

   Match this path against the provided glob-style pattern.  Return ``True``
   if matching is successful, ``False`` otherwise.  For example::

      >>> PurePath('a/b.py').full_match('a/*.py')
      True
      >>> PurePath('a/b.py').full_match('*.py')
      False
      >>> PurePath('/a/b/c.py').full_match('/a/**')
      True
      >>> PurePath('/a/b/c.py').full_match('**/*.py')
      True

   .. seealso::
      :ref:`pathlib-pattern-language` documentation.

   As with other methods, case-sensitivity follows platform defaults::

      >>> PurePosixPath('b.py').full_match('*.PY')
      False
      >>> PureWindowsPath('b.py').full_match('*.PY')
      True

   Set *case_sensitive* to ``True`` or ``False`` to override this behaviour.

   .. versionadded:: 3.13


.. method:: PurePath.match(pattern, *, case_sensitive=None)

   Match this path against the provided non-recursive glob-style pattern.
   Return ``True`` if matching is successful, ``False`` otherwise.

   This method is similar to :meth:`~PurePath.full_match`, but empty patterns
   aren't allowed (:exc:`ValueError` is raised), the recursive wildcard
   "``**``" isn't supported (it acts like non-recursive "``*``"), and if a
   relative pattern is provided, then matching is done from the right::

      >>> PurePath('a/b.py').match('*.py')
      True
      >>> PurePath('/a/b/c.py').match('b/*.py')
      True
      >>> PurePath('/a/b/c.py').match('a/*.py')
      False

   .. versionchanged:: 3.12
      The *pattern* parameter accepts a :term:`path-like object`.

   .. versionchanged:: 3.12
      The *case_sensitive* parameter was added.


.. method:: PurePath.relative_to(other, walk_up=False)

   Compute a version of this path relative to the path represented by
   *other*.  If it's impossible, :exc:`ValueError` is raised::

      >>> p = PurePosixPath('/etc/passwd')
      >>> p.relative_to('/')
      PurePosixPath('etc/passwd')
      >>> p.relative_to('/etc')
      PurePosixPath('passwd')
      >>> p.relative_to('/usr')
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "pathlib.py", line 941, in relative_to
          raise ValueError(error_message.format(str(self), str(formatted)))
      ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other is absolute.

   When *walk_up* is false (the default), the path must start with *other*.
   When the argument is true, ``..`` entries may be added to form the
   relative path. In all other cases, such as the paths referencing
   different drives, :exc:`ValueError` is raised.::

      >>> p.relative_to('/usr', walk_up=True)
      PurePosixPath('../etc/passwd')
      >>> p.relative_to('foo', walk_up=True)
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "pathlib.py", line 941, in relative_to
          raise ValueError(error_message.format(str(self), str(formatted)))
      ValueError: '/etc/passwd' is not on the same drive as 'foo' OR one path is relative and the other is absolute.

   .. warning::
      This function is part of :class:`PurePath` and works with strings.
      It does not check or access the underlying file structure.
      This can impact the *walk_up* option as it assumes that no symlinks
      are present in the path; call :meth:`~Path.resolve` first if
      necessary to resolve symlinks.

   .. versionchanged:: 3.12
      The *walk_up* parameter was added (old behavior is the same as ``walk_up=False``).

   .. deprecated-removed:: 3.12 3.14

      Passing additional positional arguments is deprecated; if supplied,
      they are joined with *other*.

.. method:: PurePath.with_name(name)

   Return a new path with the :attr:`name` changed.  If the original path
   doesn't have a name, ValueError is raised::

      >>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
      >>> p.with_name('setup.py')
      PureWindowsPath('c:/Downloads/setup.py')
      >>> p = PureWindowsPath('c:/')
      >>> p.with_name('setup.py')
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/home/antoine/cpython/default/Lib/pathlib.py", line 751, in with_name
          raise ValueError("%r has an empty name" % (self,))
      ValueError: PureWindowsPath('c:/') has an empty name


.. method:: PurePath.with_stem(stem)

   Return a new path with the :attr:`stem` changed.  If the original path
   doesn't have a name, ValueError is raised::

      >>> p = PureWindowsPath('c:/Downloads/draft.txt')
      >>> p.with_stem('final')
      PureWindowsPath('c:/Downloads/final.txt')
      >>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
      >>> p.with_stem('lib')
      PureWindowsPath('c:/Downloads/lib.gz')
      >>> p = PureWindowsPath('c:/')
      >>> p.with_stem('')
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/home/antoine/cpython/default/Lib/pathlib.py", line 861, in with_stem
          return self.with_name(stem + self.suffix)
        File "/home/antoine/cpython/default/Lib/pathlib.py", line 851, in with_name
          raise ValueError("%r has an empty name" % (self,))
      ValueError: PureWindowsPath('c:/') has an empty name

   .. versionadded:: 3.9


.. method:: PurePath.with_suffix(suffix)

   Return a new path with the :attr:`suffix` changed.  If the original path
   doesn't have a suffix, the new *suffix* is appended instead.  If the
   *suffix* is an empty string, the original suffix is removed::

      >>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
      >>> p.with_suffix('.bz2')
      PureWindowsPath('c:/Downloads/pathlib.tar.bz2')
      >>> p = PureWindowsPath('README')
      >>> p.with_suffix('.txt')
      PureWindowsPath('README.txt')
      >>> p = PureWindowsPath('README.txt')
      >>> p.with_suffix('')
      PureWindowsPath('README')

   .. versionchanged:: 3.14

      A single dot ("``.``") is considered a valid suffix. In previous
      versions, :exc:`ValueError` is raised if a single dot is supplied.


.. method:: PurePath.with_segments(*pathsegments)

   Create a new path object of the same type by combining the given
   *pathsegments*. This method is called whenever a derivative path is created,
   such as from :attr:`parent` and :meth:`relative_to`. Subclasses may
   override this method to pass information to derivative paths, for example::

      from pathlib import PurePosixPath

      class MyPath(PurePosixPath):
          def __init__(self, *pathsegments, session_id):
              super().__init__(*pathsegments)
              self.session_id = session_id

          def with_segments(self, *pathsegments):
              return type(self)(*pathsegments, session_id=self.session_id)

      etc = MyPath('/etc', session_id=42)
      hosts = etc / 'hosts'
      print(hosts.session_id)  # 42

   .. versionadded:: 3.12


.. _concrete-paths:


Concrete paths
--------------

Concrete paths are subclasses of the pure path classes.  In addition to
operations provided by the latter, they also provide methods to do system
calls on path objects.  There are three ways to instantiate concrete paths:

.. class:: Path(*pathsegments)

   A subclass of :class:`PurePath`, this class represents concrete paths of
   the system's path flavour (instantiating it creates either a
   :class:`PosixPath` or a :class:`WindowsPath`)::

      >>> Path('setup.py')
      PosixPath('setup.py')

   *pathsegments* is specified similarly to :class:`PurePath`.

.. class:: PosixPath(*pathsegments)

   A subclass of :class:`Path` and :class:`PurePosixPath`, this class
   represents concrete non-Windows filesystem paths::

      >>> PosixPath('/etc/hosts')
      PosixPath('/etc/hosts')

   *pathsegments* is specified similarly to :class:`PurePath`.

   .. versionchanged:: 3.13
      Raises :exc:`UnsupportedOperation` on Windows. In previous versions,
      :exc:`NotImplementedError` was raised instead.


.. class:: WindowsPath(*pathsegments)

   A subclass of :class:`Path` and :class:`PureWindowsPath`, this class
   represents concrete Windows filesystem paths::

      >>> WindowsPath('c:/', 'Users', 'Ximénez')
      WindowsPath('c:/Users/Ximénez')

   *pathsegments* is specified similarly to :class:`PurePath`.

   .. versionchanged:: 3.13
      Raises :exc:`UnsupportedOperation` on non-Windows platforms. In previous
      versions, :exc:`NotImplementedError` was raised instead.


You can only instantiate the class flavour that corresponds to your system
(allowing system calls on non-compatible path flavours could lead to
bugs or failures in your application)::

   >>> import os
   >>> os.name
   'posix'
   >>> Path('setup.py')
   PosixPath('setup.py')
   >>> PosixPath('setup.py')
   PosixPath('setup.py')
   >>> WindowsPath('setup.py')
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
     File "pathlib.py", line 798, in __new__
       % (cls.__name__,))
   UnsupportedOperation: cannot instantiate 'WindowsPath' on your system

Some concrete path methods can raise an :exc:`OSError` if a system call fails
(for example because the path doesn't exist).


Parsing and generating URIs
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Concrete path objects can be created from, and represented as, 'file' URIs
conforming to :rfc:`8089`.

.. note::

   File URIs are not portable across machines with different
   :ref:`filesystem encodings <filesystem-encoding>`.

.. classmethod:: Path.from_uri(uri)

   Return a new path object from parsing a 'file' URI. For example::

      >>> p = Path.from_uri('file:///etc/hosts')
      PosixPath('/etc/hosts')

   On Windows, DOS device and UNC paths may be parsed from URIs::

      >>> p = Path.from_uri('file:///c:/windows')
      WindowsPath('c:/windows')
      >>> p = Path.from_uri('file://server/share')
      WindowsPath('//server/share')

   Several variant forms are supported::

      >>> p = Path.from_uri('file:////server/share')
      WindowsPath('//server/share')
      >>> p = Path.from_uri('file://///server/share')
      WindowsPath('//server/share')
      >>> p = Path.from_uri('file:c:/windows')
      WindowsPath('c:/windows')
      >>> p = Path.from_uri('file:/c|/windows')
      WindowsPath('c:/windows')

   :exc:`ValueError` is raised if the URI does not start with ``file:``, or
   the parsed path isn't absolute.

   .. versionadded:: 3.13

   .. versionchanged:: 3.14
      The URL authority is discarded if it matches the local hostname.
      Otherwise, if the authority isn't empty or ``localhost``, then on
      Windows a UNC path is returned (as before), and on other platforms a
      :exc:`ValueError` is raised.


.. method:: Path.as_uri()

   Represent the path as a 'file' URI.  :exc:`ValueError` is raised if
   the path isn't absolute.

   .. code-block:: pycon

      >>> p = PosixPath('/etc/passwd')
      >>> p.as_uri()
      'file:///etc/passwd'
      >>> p = WindowsPath('c:/Windows')
      >>> p.as_uri()
      'file:///c:/Windows'

   .. deprecated-removed:: 3.14 3.19

      Calling this method from :class:`PurePath` rather than :class:`Path` is
      possible but deprecated. The method's use of :func:`os.fsencode` makes
      it strictly impure.


Expanding and resolving paths
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. classmethod:: Path.home()

   Return a new path object representing the user's home directory (as
   returned by :func:`os.path.expanduser` with ``~`` construct). If the home
   directory can't be resolved, :exc:`RuntimeError` is raised.

   ::

      >>> Path.home()
      PosixPath('/home/antoine')

   .. versionadded:: 3.5


.. method:: Path.expanduser()

   Return a new path with expanded ``~`` and ``~user`` constructs,
   as returned by :meth:`os.path.expanduser`. If a home directory can't be
   resolved, :exc:`RuntimeError` is raised.

   ::

      >>> p = PosixPath('~/films/Monty Python')
      >>> p.expanduser()
      PosixPath('/home/eric/films/Monty Python')

   .. versionadded:: 3.5


.. classmethod:: Path.cwd()

   Return a new path object representing the current directory (as returned
   by :func:`os.getcwd`)::

      >>> Path.cwd()
      PosixPath('/home/antoine/pathlib')


.. method:: Path.absolute()

   Make the path absolute, without normalization or resolving symlinks.
   Returns a new path object::

      >>> p = Path('tests')
      >>> p
      PosixPath('tests')
      >>> p.absolute()
      PosixPath('/home/antoine/pathlib/tests')


.. method:: Path.resolve(strict=False)

   Make the path absolute, resolving any symlinks.  A new path object is
   returned::

      >>> p = Path()
      >>> p
      PosixPath('.')
      >>> p.resolve()
      PosixPath('/home/antoine/pathlib')

   "``..``" components are also eliminated (this is the only method to do so)::

      >>> p = Path('docs/../setup.py')
      >>> p.resolve()
      PosixPath('/home/antoine/pathlib/setup.py')

   If a path doesn't exist or a symlink loop is encountered, and *strict* is
   ``True``, :exc:`OSError` is raised.  If *strict* is ``False``, the path is
   resolved as far as possible and any remainder is appended without checking
   whether it exists.

   .. versionchanged:: 3.6
      The *strict* parameter was added (pre-3.6 behavior is strict).

   .. versionchanged:: 3.13
      Symlink loops are treated like other errors: :exc:`OSError` is raised in
      strict mode, and no exception is raised in non-strict mode. In previous
      versions, :exc:`RuntimeError` is raised no matter the value of *strict*.


.. method:: Path.readlink()

   Return the path to which the symbolic link points (as returned by
   :func:`os.readlink`)::

      >>> p = Path('mylink')
      >>> p.symlink_to('setup.py')
      >>> p.readlink()
      PosixPath('setup.py')

   .. versionadded:: 3.9

   .. versionchanged:: 3.13
      Raises :exc:`UnsupportedOperation` if :func:`os.readlink` is not
      available. In previous versions, :exc:`NotImplementedError` was raised.


Querying file type and status
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. versionchanged:: 3.8

   :meth:`~Path.exists`, :meth:`~Path.is_dir`, :meth:`~Path.is_file`,
   :meth:`~Path.is_mount`, :meth:`~Path.is_symlink`,
   :meth:`~Path.is_block_device`, :meth:`~Path.is_char_device`,
   :meth:`~Path.is_fifo`, :meth:`~Path.is_socket` now return ``False``
   instead of raising an exception for paths that contain characters
   unrepresentable at the OS level.

.. versionchanged:: 3.14

   The methods given above now return ``False`` instead of raising any
   :exc:`OSError` exception from the operating system. In previous versions,
   some kinds of :exc:`OSError` exception are raised, and others suppressed.
   The new behaviour is consistent with :func:`os.path.exists`,
   :func:`os.path.isdir`, etc. Use :meth:`~Path.stat` to retrieve the file
   status without suppressing exceptions.


.. method:: Path.stat(*, follow_symlinks=True)

   Return an :class:`os.stat_result` object containing information about this path, like :func:`os.stat`.
   The result is looked up at each call to this method.

   This method normally follows symlinks; to stat a symlink add the argument
   ``follow_symlinks=False``, or use :meth:`~Path.lstat`.

   ::

      >>> p = Path('setup.py')
      >>> p.stat().st_size
      956
      >>> p.stat().st_mtime
      1327883547.852554

   .. versionchanged:: 3.10
      The *follow_symlinks* parameter was added.


.. method:: Path.lstat()

   Like :meth:`Path.stat` but, if the path points to a symbolic link, return
   the symbolic link's information rather than its target's.


.. method:: Path.exists(*, follow_symlinks=True)

   Return ``True`` if the path points to an existing file or directory.
   ``False`` will be returned if the path is invalid, inaccessible or missing.
   Use :meth:`Path.stat` to distinguish between these cases.

   This method normally follows symlinks; to check if a symlink exists, add
   the argument ``follow_symlinks=False``.

   ::

      >>> Path('.').exists()
      True
      >>> Path('setup.py').exists()
      True
      >>> Path('/etc').exists()
      True
      >>> Path('nonexistentfile').exists()
      False

   .. versionchanged:: 3.12
      The *follow_symlinks* parameter was added.


.. method:: Path.is_file(*, follow_symlinks=True)

   Return ``True`` if the path points to a regular file. ``False`` will be
   returned if the path is invalid, inaccessible or missing, or if it points
   to something other than a regular file. Use :meth:`Path.stat` to
   distinguish between these cases.

   This method normally follows symlinks; to exclude symlinks, add the
   argument ``follow_symlinks=False``.

   .. versionchanged:: 3.13
      The *follow_symlinks* parameter was added.


.. method:: Path.is_dir(*, follow_symlinks=True)

   Return ``True`` if the path points to a directory. ``False`` will be
   returned if the path is invalid, inaccessible or missing, or if it points
   to something other than a directory. Use :meth:`Path.stat` to distinguish
   between these cases.

   This method normally follows symlinks; to exclude symlinks to directories,
   add the argument ``follow_symlinks=False``.

   .. versionchanged:: 3.13
      The *follow_symlinks* parameter was added.


.. method:: Path.is_symlink()

   Return ``True`` if the path points to a symbolic link, even if that symlink
   is broken. ``False`` will be returned if the path is invalid, inaccessible
   or missing, or if it points to something other than a symbolic link. Use
   :meth:`Path.stat` to distinguish between these cases.


.. method:: Path.is_junction()

   Return ``True`` if the path points to a junction, and ``False`` for any other
   type of file. Currently only Windows supports junctions.

   .. versionadded:: 3.12


.. method:: Path.is_mount()

   Return ``True`` if the path is a :dfn:`mount point`: a point in a
   file system where a different file system has been mounted.  On POSIX, the
   function checks whether *path*'s parent, :file:`path/..`, is on a different
   device than *path*, or whether :file:`path/..` and *path* point to the same
   i-node on the same device --- this should detect mount points for all Unix
   and POSIX variants.  On Windows, a mount point is considered to be a drive
   letter root (e.g. ``c:\``), a UNC share (e.g. ``\\server\share``), or a
   mounted filesystem directory.

   .. versionadded:: 3.7

   .. versionchanged:: 3.12
      Windows support was added.

.. method:: Path.is_socket()

   Return ``True`` if the path points to a Unix socket. ``False`` will be
   returned if the path is invalid, inaccessible or missing, or if it points
   to something other than a Unix socket. Use :meth:`Path.stat` to
   distinguish between these cases.


.. method:: Path.is_fifo()

   Return ``True`` if the path points to a FIFO. ``False`` will be returned if
   the path is invalid, inaccessible or missing, or if it points to something
   other than a FIFO. Use :meth:`Path.stat` to distinguish between these
   cases.


.. method:: Path.is_block_device()

   Return ``True`` if the path points to a block device. ``False`` will be
   returned if the path is invalid, inaccessible or missing, or if it points
   to something other than a block device. Use :meth:`Path.stat` to
   distinguish between these cases.


.. method:: Path.is_char_device()

   Return ``True`` if the path points to a character device. ``False`` will be
   returned if the path is invalid, inaccessible or missing, or if it points
   to something other than a character device. Use :meth:`Path.stat` to
   distinguish between these cases.


.. method:: Path.samefile(other_path)

   Return whether this path points to the same file as *other_path*, which
   can be either a Path object, or a string.  The semantics are similar
   to :func:`os.path.samefile` and :func:`os.path.samestat`.

   An :exc:`OSError` can be raised if either file cannot be accessed for some
   reason.

   ::

      >>> p = Path('spam')
      >>> q = Path('eggs')
      >>> p.samefile(q)
      False
      >>> p.samefile('spam')
      True

   .. versionadded:: 3.5


.. attribute:: Path.info

   A :class:`~pathlib.types.PathInfo` object that supports querying file type
   information. The object exposes methods that cache their results, which can
   help reduce the number of system calls needed when switching on file type.
   For example::

      >>> p = Path('src')
      >>> if p.info.is_symlink():
      ...     print('symlink')
      ... elif p.info.is_dir():
      ...     print('directory')
      ... elif p.info.exists():
      ...     print('something else')
      ... else:
      ...     print('not found')
      ...
      directory

   If the path was generated from :meth:`Path.iterdir` then this attribute is
   initialized with some information about the file type gleaned from scanning
   the parent directory. Merely accessing :attr:`Path.info` does not perform
   any filesystem queries.

   To fetch up-to-date information, it's best to call :meth:`Path.is_dir`,
   :meth:`~Path.is_file` and :meth:`~Path.is_symlink` rather than methods of
   this attribute. There is no way to reset the cache; instead you can create
   a new path object with an empty info cache via ``p = Path(p)``.

   .. versionadded:: 3.14


Reading and writing files
^^^^^^^^^^^^^^^^^^^^^^^^^


.. method:: Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)

   Open the file pointed to by the path, like the built-in :func:`open`
   function does::

      >>> p = Path('setup.py')
      >>> with p.open() as f:
      ...     f.readline()
      ...
      '#!/usr/bin/env python3\n'


.. method:: Path.read_text(encoding=None, errors=None, newline=None)

   Return the decoded contents of the pointed-to file as a string::

      >>> p = Path('my_text_file')
      >>> p.write_text('Text file contents')
      18
      >>> p.read_text()
      'Text file contents'

   The file is opened and then closed. The optional parameters have the same
   meaning as in :func:`open`.

   .. versionadded:: 3.5

   .. versionchanged:: 3.13
      The *newline* parameter was added.


.. method:: Path.read_bytes()

   Return the binary contents of the pointed-to file as a bytes object::

      >>> p = Path('my_binary_file')
      >>> p.write_bytes(b'Binary file contents')
      20
      >>> p.read_bytes()
      b'Binary file contents'

   .. versionadded:: 3.5


.. method:: Path.write_text(data, encoding=None, errors=None, newline=None)

   Open the file pointed to in text mode, write *data* to it, and close the
   file::

      >>> p = Path('my_text_file')
      >>> p.write_text('Text file contents')
      18
      >>> p.read_text()
      'Text file contents'

   An existing file of the same name is overwritten. The optional parameters
   have the same meaning as in :func:`open`.

   .. versionadded:: 3.5

   .. versionchanged:: 3.10
      The *newline* parameter was added.


.. method:: Path.write_bytes(data)

   Open the file pointed to in bytes mode, write *data* to it, and close the
   file::

      >>> p = Path('my_binary_file')
      >>> p.write_bytes(b'Binary file contents')
      20
      >>> p.read_bytes()
      b'Binary file contents'

   An existing file of the same name is overwritten.

   .. versionadded:: 3.5


Reading directories
^^^^^^^^^^^^^^^^^^^

.. method:: Path.iterdir()

   When the path points to a directory, yield path objects of the directory
   contents::

      >>> p = Path('docs')
      >>> for child in p.iterdir(): child
      ...
      PosixPath('docs/conf.py')
      PosixPath('docs/_templates')
      PosixPath('docs/make.bat')
      PosixPath('docs/index.rst')
      PosixPath('docs/_build')
      PosixPath('docs/_static')
      PosixPath('docs/Makefile')

   The children are yielded in arbitrary order, and the special entries
   ``'.'`` and ``'..'`` are not included.  If a file is removed from or added
   to the directory after creating the iterator, it is unspecified whether
   a path object for that file is included.

   If the path is not a directory or otherwise inaccessible, :exc:`OSError` is
   raised.


.. method:: Path.glob(pattern, *, case_sensitive=None, recurse_symlinks=False)

   Glob the given relative *pattern* in the directory represented by this path,
   yielding all matching files (of any kind)::

      >>> sorted(Path('.').glob('*.py'))
      [PosixPath('pathlib.py'), PosixPath('setup.py'), PosixPath('test_pathlib.py')]
      >>> sorted(Path('.').glob('*/*.py'))
      [PosixPath('docs/conf.py')]
      >>> sorted(Path('.').glob('**/*.py'))
      [PosixPath('build/lib/pathlib.py'),
       PosixPath('docs/conf.py'),
       PosixPath('pathlib.py'),
       PosixPath('setup.py'),
       PosixPath('test_pathlib.py')]

   .. note::
      The paths are returned in no particular order.
      If you need a specific order, sort the results.

   .. seealso::
      :ref:`pathlib-pattern-language` documentation.

   By default, or when the *case_sensitive* keyword-only argument is set to
   ``None``, this method matches paths using platform-specific casing rules:
   typically, case-sensitive on POSIX, and case-insensitive on Windows.
   Set *case_sensitive* to ``True`` or ``False`` to override this behaviour.

   By default, or when the *recurse_symlinks* keyword-only argument is set to
   ``False``, this method follows symlinks except when expanding "``**``"
   wildcards. Set *recurse_symlinks* to ``True`` to always follow symlinks.

   .. audit-event:: pathlib.Path.glob self,pattern pathlib.Path.glob

   .. versionchanged:: 3.12
      The *case_sensitive* parameter was added.

   .. versionchanged:: 3.13
      The *recurse_symlinks* parameter was added.

   .. versionchanged:: 3.13
      The *pattern* parameter accepts a :term:`path-like object`.

   .. versionchanged:: 3.13
      Any :exc:`OSError` exceptions raised from scanning the filesystem are
      suppressed. In previous versions, such exceptions are suppressed in many
      cases, but not all.


.. method:: Path.rglob(pattern, *, case_sensitive=None, recurse_symlinks=False)

   Glob the given relative *pattern* recursively.  This is like calling
   :func:`Path.glob` with "``**/``" added in front of the *pattern*.

   .. note::
      The paths are returned in no particular order.
      If you need a specific order, sort the results.

   .. seealso::
      :ref:`pathlib-pattern-language` and :meth:`Path.glob` documentation.

   .. audit-event:: pathlib.Path.rglob self,pattern pathlib.Path.rglob

   .. versionchanged:: 3.12
      The *case_sensitive* parameter was added.

   .. versionchanged:: 3.13
      The *recurse_symlinks* parameter was added.

   .. versionchanged:: 3.13
      The *pattern* parameter accepts a :term:`path-like object`.


.. method:: Path.walk(top_down=True, on_error=None, follow_symlinks=False)

   Generate the file names in a directory tree by walking the tree
   either top-down or bottom-up.

   For each directory in the directory tree rooted at *self* (including
   *self* but excluding '.' and '..'), the method yields a 3-tuple of
   ``(dirpath, dirnames, filenames)``.

   *dirpath* is a :class:`Path` to the directory currently being walked,
   *dirnames* is a list of strings for the names of subdirectories in *dirpath*
   (excluding ``'.'`` and ``'..'``), and *filenames* is a list of strings for
   the names of the non-directory files in *dirpath*. To get a full path
   (which begins with *self*) to a file or directory in *dirpath*, do
   ``dirpath / name``. Whether or not the lists are sorted is file
   system-dependent.

   If the optional argument *top_down* is true (which is the default), the triple for a
   directory is generated before the triples for any of its subdirectories
   (directories are walked top-down).  If *top_down* is false, the triple
   for a directory is generated after the triples for all of its subdirectories
   (directories are walked bottom-up). No matter the value of *top_down*, the
   list of subdirectories is retrieved before the triples for the directory and
   its subdirectories are walked.

   When *top_down* is true, the caller can modify the *dirnames* list in-place
   (for example, using :keyword:`del` or slice assignment), and :meth:`Path.walk`
   will only recurse into the subdirectories whose names remain in *dirnames*.
   This can be used to prune the search, or to impose a specific order of visiting,
   or even to inform :meth:`Path.walk` about directories the caller creates or
   renames before it resumes :meth:`Path.walk` again. Modifying *dirnames* when
   *top_down* is false has no effect on the behavior of :meth:`Path.walk` since the
   directories in *dirnames* have already been generated by the time *dirnames*
   is yielded to the caller.

   By default, errors from :func:`os.scandir` are ignored.  If the optional
   argument *on_error* is specified, it should be a callable; it will be
   called with one argument, an :exc:`OSError` instance. The callable can handle the
   error to continue the walk or re-raise it to stop the walk. Note that the
   filename is available as the ``filename`` attribute of the exception object.

   By default, :meth:`Path.walk` does not follow symbolic links, and instead adds them
   to the *filenames* list. Set *follow_symlinks* to true to resolve symlinks
   and place them in *dirnames* and *filenames* as appropriate for their targets, and
   consequently visit directories pointed to by symlinks (where supported).

   .. note::

      Be aware that setting *follow_symlinks* to true can lead to infinite
      recursion if a link points to a parent directory of itself. :meth:`Path.walk`
      does not keep track of the directories it has already visited.

   .. note::
      :meth:`Path.walk` assumes the directories it walks are not modified during
      execution. For example, if a directory from *dirnames* has been replaced
      with a symlink and *follow_symlinks* is false, :meth:`Path.walk` will
      still try to descend into it. To prevent such behavior, remove directories
      from *dirnames* as appropriate.

   .. note::

      Unlike :func:`os.walk`, :meth:`Path.walk` lists symlinks to directories in
      *filenames* if *follow_symlinks* is false.

   This example displays the number of bytes used by all files in each directory,
   while ignoring ``__pycache__`` directories::

      from pathlib import Path
      for root, dirs, files in Path("cpython/Lib/concurrent").walk(on_error=print):
        print(
            root,
            "consumes",
            sum((root / file).stat().st_size for file in files),
            "bytes in",
            len(files),
            "non-directory files"
        )
        if '__pycache__' in dirs:
              dirs.remove('__pycache__')

   This next example is a simple implementation of :func:`shutil.rmtree`.
   Walking the tree bottom-up is essential as :func:`rmdir` doesn't allow
   deleting a directory before it is empty::

      # Delete everything reachable from the directory "top".
      # CAUTION:  This is dangerous! For example, if top == Path('/'),
      # it could delete all of your files.
      for root, dirs, files in top.walk(top_down=False):
          for name in files:
              (root / name).unlink()
          for name in dirs:
              (root / name).rmdir()

   .. versionadded:: 3.12


Creating files and directories
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. method:: Path.touch(mode=0o666, exist_ok=True)

   Create a file at this given path.  If *mode* is given, it is combined
   with the process's ``umask`` value to determine the file mode and access
   flags.  If the file already exists, the function succeeds when *exist_ok*
   is true (and its modification time is updated to the current time),
   otherwise :exc:`FileExistsError` is raised.

   .. seealso::
      The :meth:`~Path.open`, :meth:`~Path.write_text` and
      :meth:`~Path.write_bytes` methods are often used to create files.


.. method:: Path.mkdir(mode=0o777, parents=False, exist_ok=False)

   Create a new directory at this given path.  If *mode* is given, it is
   combined with the process's ``umask`` value to determine the file mode
   and access flags.  If the path already exists, :exc:`FileExistsError`
   is raised.

   If *parents* is true, any missing parents of this path are created
   as needed; they are created with the default permissions without taking
   *mode* into account (mimicking the POSIX ``mkdir -p`` command).

   If *parents* is false (the default), a missing parent raises
   :exc:`FileNotFoundError`.

   If *exist_ok* is false (the default), :exc:`FileExistsError` is
   raised if the target directory already exists.

   If *exist_ok* is true, :exc:`FileExistsError` will not be raised unless the given
   path already exists in the file system and is not a directory (same
   behavior as the POSIX ``mkdir -p`` command).

   .. versionchanged:: 3.5
      The *exist_ok* parameter was added.


.. method:: Path.symlink_to(target, target_is_directory=False)

   Make this path a symbolic link pointing to *target*.

   On Windows, a symlink represents either a file or a directory, and does not
   morph to the target dynamically.  If the target is present, the type of the
   symlink will be created to match. Otherwise, the symlink will be created
   as a directory if *target_is_directory* is true or a file symlink (the
   default) otherwise.  On non-Windows platforms, *target_is_directory* is ignored.

   ::

      >>> p = Path('mylink')
      >>> p.symlink_to('setup.py')
      >>> p.resolve()
      PosixPath('/home/antoine/pathlib/setup.py')
      >>> p.stat().st_size
      956
      >>> p.lstat().st_size
      8

   .. note::
      The order of arguments (link, target) is the reverse
      of :func:`os.symlink`'s.

   .. versionchanged:: 3.13
      Raises :exc:`UnsupportedOperation` if :func:`os.symlink` is not
      available. In previous versions, :exc:`NotImplementedError` was raised.


.. method:: Path.hardlink_to(target)

   Make this path a hard link to the same file as *target*.

   .. note::
      The order of arguments (link, target) is the reverse
      of :func:`os.link`'s.

   .. versionadded:: 3.10

   .. versionchanged:: 3.13
      Raises :exc:`UnsupportedOperation` if :func:`os.link` is not
      available. In previous versions, :exc:`NotImplementedError` was raised.


Copying, moving and deleting
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. method:: Path.copy(target, *, follow_symlinks=True, preserve_metadata=False)

   Copy this file or directory tree to the given *target*, and return a new
   :class:`!Path` instance pointing to *target*.

   If the source is a file, the target will be replaced if it is an existing
   file. If the source is a symlink and *follow_symlinks* is true (the
   default), the symlink's target is copied. Otherwise, the symlink is
   recreated at the destination.

   If *preserve_metadata* is false (the default), only directory structures
   and file data are guaranteed to be copied. Set *preserve_metadata* to true
   to ensure that file and directory permissions, flags, last access and
   modification times, and extended attributes are copied where supported.
   This argument has no effect when copying files on Windows (where
   metadata is always preserved).

   .. note::
      Where supported by the operating system and file system, this method
      performs a lightweight copy, where data blocks are only copied when
      modified. This is known as copy-on-write.

   .. versionadded:: 3.14


.. method:: Path.copy_into(target_dir, *, follow_symlinks=True, \
                           preserve_metadata=False)

   Copy this file or directory tree into the given *target_dir*, which should
   be an existing directory. Other arguments are handled identically to
   :meth:`Path.copy`. Returns a new :class:`!Path` instance pointing to the
   copy.

   .. versionadded:: 3.14


.. method:: Path.rename(target)

   Rename this file or directory to the given *target*, and return a new
   :class:`!Path` instance pointing to *target*.  On Unix, if *target* exists
   and is a file, it will be replaced silently if the user has permission.
   On Windows, if *target* exists, :exc:`FileExistsError` will be raised.
   *target* can be either a string or another path object::

      >>> p = Path('foo')
      >>> p.open('w').write('some text')
      9
      >>> target = Path('bar')
      >>> p.rename(target)
      PosixPath('bar')
      >>> target.open().read()
      'some text'

   The target path may be absolute or relative. Relative paths are interpreted
   relative to the current working directory, *not* the directory of the
   :class:`!Path` object.

   It is implemented in terms of :func:`os.rename` and gives the same guarantees.

   .. versionchanged:: 3.8
      Added return value, return the new :class:`!Path` instance.


.. method:: Path.replace(target)

   Rename this file or directory to the given *target*, and return a new
   :class:`!Path` instance pointing to *target*.  If *target* points to an
   existing file or empty directory, it will be unconditionally replaced.

   The target path may be absolute or relative. Relative paths are interpreted
   relative to the current working directory, *not* the directory of the
   :class:`!Path` object.

   .. versionchanged:: 3.8
      Added return value, return the new :class:`!Path` instance.


.. method:: Path.move(target)

   Move this file or directory tree to the given *target*, and return a new
   :class:`!Path` instance pointing to *target*.

   If the *target* doesn't exist it will be created. If both this path and the
   *target* are existing files, then the target is overwritten. If both paths
   point to the same file or directory, or the *target* is a non-empty
   directory, then :exc:`OSError` is raised.

   If both paths are on the same filesystem, the move is performed with
   :func:`os.replace`. Otherwise, this path is copied (preserving metadata and
   symlinks) and then deleted.

   .. versionadded:: 3.14


.. method:: Path.move_into(target_dir)

   Move this file or directory tree into the given *target_dir*, which should
   be an existing directory. Returns a new :class:`!Path` instance pointing to
   the moved path.

   .. versionadded:: 3.14


.. method:: Path.unlink(missing_ok=False)

   Remove this file or symbolic link.  If the path points to a directory,
   use :func:`Path.rmdir` instead.

   If *missing_ok* is false (the default), :exc:`FileNotFoundError` is
   raised if the path does not exist.

   If *missing_ok* is true, :exc:`FileNotFoundError` exceptions will be
   ignored (same behavior as the POSIX ``rm -f`` command).

   .. versionchanged:: 3.8
      The *missing_ok* parameter was added.


.. method:: Path.rmdir()

   Remove this directory.  The directory must be empty.


Permissions and ownership
^^^^^^^^^^^^^^^^^^^^^^^^^

.. method:: Path.owner(*, follow_symlinks=True)

   Return the name of the user owning the file. :exc:`KeyError` is raised
   if the file's user identifier (UID) isn't found in the system database.

   This method normally follows symlinks; to get the owner of the symlink, add
   the argument ``follow_symlinks=False``.

   .. versionchanged:: 3.13
      Raises :exc:`UnsupportedOperation` if the :mod:`pwd` module is not
      available. In earlier versions, :exc:`NotImplementedError` was raised.

   .. versionchanged:: 3.13
      The *follow_symlinks* parameter was added.


.. method:: Path.group(*, follow_symlinks=True)

   Return the name of the group owning the file. :exc:`KeyError` is raised
   if the file's group identifier (GID) isn't found in the system database.

   This method normally follows symlinks; to get the group of the symlink, add
   the argument ``follow_symlinks=False``.

   .. versionchanged:: 3.13
      Raises :exc:`UnsupportedOperation` if the :mod:`grp` module is not
      available. In earlier versions, :exc:`NotImplementedError` was raised.

   .. versionchanged:: 3.13
      The *follow_symlinks* parameter was added.


.. method:: Path.chmod(mode, *, follow_symlinks=True)

   Change the file mode and permissions, like :func:`os.chmod`.

   This method normally follows symlinks. Some Unix flavours support changing
   permissions on the symlink itself; on these platforms you may add the
   argument ``follow_symlinks=False``, or use :meth:`~Path.lchmod`.

   ::

      >>> p = Path('setup.py')
      >>> p.stat().st_mode
      33277
      >>> p.chmod(0o444)
      >>> p.stat().st_mode
      33060

   .. versionchanged:: 3.10
      The *follow_symlinks* parameter was added.


.. method:: Path.lchmod(mode)

   Like :meth:`Path.chmod` but, if the path points to a symbolic link, the
   symbolic link's mode is changed rather than its target's.


.. _pathlib-pattern-language:

Pattern language
----------------

The following wildcards are supported in patterns for
:meth:`~PurePath.full_match`, :meth:`~Path.glob` and :meth:`~Path.rglob`:

``**`` (entire segment)
  Matches any number of file or directory segments, including zero.
``*`` (entire segment)
  Matches one file or directory segment.
``*`` (part of a segment)
  Matches any number of non-separator characters, including zero.
``?``
  Matches one non-separator character.
``[seq]``
  Matches one character in *seq*, where *seq* is a sequence of characters.
  Range expressions are supported; for example, ``[a-z]`` matches any lowercase ASCII letter.
  Multiple ranges can be combined: ``[a-zA-Z0-9_]`` matches any ASCII letter, digit, or underscore.

``[!seq]``
  Matches one character not in *seq*, where *seq* follows the same rules as above.

For a literal match, wrap the meta-characters in brackets.
For example, ``"[?]"`` matches the character ``"?"``.

The "``**``" wildcard enables recursive globbing. A few examples:

=========================  ===========================================
Pattern                    Meaning
=========================  ===========================================
"``**/*``"                 Any path with at least one segment.
"``**/*.py``"              Any path with a final segment ending "``.py``".
"``assets/**``"            Any path starting with "``assets/``".
"``assets/**/*``"          Any path starting with "``assets/``", excluding "``assets/``" itself.
=========================  ===========================================

.. note::
   Globbing with the "``**``" wildcard visits every directory in the tree.
   Large directory trees may take a long time to search.

.. versionchanged:: 3.13
   Globbing with a pattern that ends with "``**``" returns both files and
   directories. In previous versions, only directories were returned.

In :meth:`Path.glob` and :meth:`~Path.rglob`, a trailing slash may be added to
the pattern to match only directories.

.. versionchanged:: 3.11
   Globbing with a pattern that ends with a pathname components separator
   (:data:`~os.sep` or :data:`~os.altsep`) returns only directories.


Comparison to the :mod:`glob` module
------------------------------------

The patterns accepted and results generated by :meth:`Path.glob` and
:meth:`Path.rglob` differ slightly from those by the :mod:`glob` module:

1. Files beginning with a dot are not special in pathlib. This is
   like passing ``include_hidden=True`` to :func:`glob.glob`.
2. "``**``" pattern components are always recursive in pathlib. This is like
   passing ``recursive=True`` to :func:`glob.glob`.
3. "``**``" pattern components do not follow symlinks by default in pathlib.
   This behaviour has no equivalent in :func:`glob.glob`, but you can pass
   ``recurse_symlinks=True`` to :meth:`Path.glob` for compatible behaviour.
4. Like all :class:`PurePath` and :class:`Path` objects, the values returned
   from :meth:`Path.glob` and :meth:`Path.rglob` don't include trailing
   slashes.
5. The values returned from pathlib's ``path.glob()`` and ``path.rglob()``
   include the *path* as a prefix, unlike the results of
   ``glob.glob(root_dir=path)``.
6. The values returned from pathlib's ``path.glob()`` and ``path.rglob()``
   may include *path* itself, for example when globbing "``**``", whereas the
   results of ``glob.glob(root_dir=path)`` never include an empty string that
   would correspond to *path*.


Comparison to the :mod:`os` and :mod:`os.path` modules
------------------------------------------------------

pathlib implements path operations using :class:`PurePath` and :class:`Path`
objects, and so it's said to be *object-oriented*. On the other hand, the
:mod:`os` and :mod:`os.path` modules supply functions that work with low-level
``str`` and ``bytes`` objects, which is a more *procedural* approach. Some
users consider the object-oriented style to be more readable.

Many functions in :mod:`os` and :mod:`os.path` support ``bytes`` paths and
:ref:`paths relative to directory descriptors <dir_fd>`. These features aren't
available in pathlib.

Python's ``str`` and ``bytes`` types, and portions of the :mod:`os` and
:mod:`os.path` modules, are written in C and are very speedy. pathlib is
written in pure Python and is often slower, but rarely slow enough to matter.

pathlib's path normalization is slightly more opinionated and consistent than
:mod:`os.path`. For example, whereas :func:`os.path.abspath` eliminates
"``..``" segments from a path, which may change its meaning if symlinks are
involved, :meth:`Path.absolute` preserves these segments for greater safety.

pathlib's path normalization may render it unsuitable for some applications:

1. pathlib normalizes ``Path("my_folder/")`` to ``Path("my_folder")``, which
   changes a path's meaning when supplied to various operating system APIs and
   command-line utilities. Specifically, the absence of a trailing separator
   may allow the path to be resolved as either a file or directory, rather
   than a directory only.
2. pathlib normalizes ``Path("./my_program")`` to ``Path("my_program")``,
   which changes a path's meaning when used as an executable search path, such
   as in a shell or when spawning a child process. Specifically, the absence
   of a separator in the path may force it to be looked up in :envvar:`PATH`
   rather than the current directory.

As a consequence of these differences, pathlib is not a drop-in replacement
for :mod:`os.path`.


Corresponding tools
^^^^^^^^^^^^^^^^^^^

Below is a table mapping various :mod:`os` functions to their corresponding
:class:`PurePath`/:class:`Path` equivalent.

=====================================   ==============================================
:mod:`os` and :mod:`os.path`            :mod:`pathlib`
=====================================   ==============================================
:func:`os.path.dirname`                 :attr:`PurePath.parent`
:func:`os.path.basename`                :attr:`PurePath.name`
:func:`os.path.splitext`                :attr:`PurePath.stem`, :attr:`PurePath.suffix`
:func:`os.path.join`                    :meth:`PurePath.joinpath`
:func:`os.path.isabs`                   :meth:`PurePath.is_absolute`
:func:`os.path.relpath`                 :meth:`PurePath.relative_to` [1]_
:func:`os.path.expanduser`              :meth:`Path.expanduser` [2]_
:func:`os.path.realpath`                :meth:`Path.resolve`
:func:`os.path.abspath`                 :meth:`Path.absolute` [3]_
:func:`os.path.exists`                  :meth:`Path.exists`
:func:`os.path.isfile`                  :meth:`Path.is_file`
:func:`os.path.isdir`                   :meth:`Path.is_dir`
:func:`os.path.islink`                  :meth:`Path.is_symlink`
:func:`os.path.isjunction`              :meth:`Path.is_junction`
:func:`os.path.ismount`                 :meth:`Path.is_mount`
:func:`os.path.samefile`                :meth:`Path.samefile`
:func:`os.getcwd`                       :meth:`Path.cwd`
:func:`os.stat`                         :meth:`Path.stat`
:func:`os.lstat`                        :meth:`Path.lstat`
:func:`os.listdir`                      :meth:`Path.iterdir`
:func:`os.walk`                         :meth:`Path.walk` [4]_
:func:`os.mkdir`, :func:`os.makedirs`   :meth:`Path.mkdir`
:func:`os.link`                         :meth:`Path.hardlink_to`
:func:`os.symlink`                      :meth:`Path.symlink_to`
:func:`os.readlink`                     :meth:`Path.readlink`
:func:`os.rename`                       :meth:`Path.rename`
:func:`os.replace`                      :meth:`Path.replace`
:func:`os.remove`, :func:`os.unlink`    :meth:`Path.unlink`
:func:`os.rmdir`                        :meth:`Path.rmdir`
:func:`os.chmod`                        :meth:`Path.chmod`
:func:`os.lchmod`                       :meth:`Path.lchmod`
=====================================   ==============================================

.. rubric:: Footnotes

.. [1] :func:`os.path.relpath` calls :func:`~os.path.abspath` to make paths
   absolute and remove "``..``" parts, whereas :meth:`PurePath.relative_to`
   is a lexical operation that raises :exc:`ValueError` when its inputs'
   anchors differ (e.g. if one path is absolute and the other relative.)
.. [2] :func:`os.path.expanduser` returns the path unchanged if the home
   directory can't be resolved, whereas :meth:`Path.expanduser` raises
   :exc:`RuntimeError`.
.. [3] :func:`os.path.abspath` removes "``..``" components without resolving
   symlinks, which may change the meaning of the path, whereas
   :meth:`Path.absolute` leaves any "``..``" components in the path.
.. [4] :func:`os.walk` always follows symlinks when categorizing paths into
   *dirnames* and *filenames*, whereas :meth:`Path.walk` categorizes all
   symlinks into *filenames* when *follow_symlinks* is false (the default.)


Protocols
---------

.. module:: pathlib.types
   :synopsis: pathlib types for static type checking


The :mod:`pathlib.types` module provides types for static type checking.

.. versionadded:: 3.14


.. class:: PathInfo()

   A :class:`typing.Protocol` describing the
   :attr:`Path.info <pathlib.Path.info>` attribute. Implementations may
   return cached results from their methods.

   .. method:: exists(*, follow_symlinks=True)

      Return ``True`` if the path is an existing file or directory, or any
      other kind of file; return ``False`` if the path doesn't exist.

      If *follow_symlinks* is ``False``, return ``True`` for symlinks without
      checking if their targets exist.

   .. method:: is_dir(*, follow_symlinks=True)

      Return ``True`` if the path is a directory, or a symbolic link pointing
      to a directory; return ``False`` if the path is (or points to) any other
      kind of file, or if it doesn't exist.

      If *follow_symlinks* is ``False``, return ``True`` only if the path
      is a directory (without following symlinks); return ``False`` if the
      path is any other kind of file, or if it doesn't exist.

   .. method:: is_file(*, follow_symlinks=True)

      Return ``True`` if the path is a file, or a symbolic link pointing to
      a file; return ``False`` if the path is (or points to) a directory or
      other non-file, or if it doesn't exist.

      If *follow_symlinks* is ``False``, return ``True`` only if the path
      is a file (without following symlinks); return ``False`` if the path
      is a directory or other non-file, or if it doesn't exist.

   .. method:: is_symlink()

      Return ``True`` if the path is a symbolic link (even if broken); return
      ``False`` if the path is a directory or any kind of file, or if it
      doesn't exist.
