diff --git a/Doc/library/pathlib-inheritance.png b/Doc/library/pathlib-inheritance.png new file mode 100644 index 0000000000000000000000000000000000000000..b81c3deb6049d83051337776fe5c4f3de751e1cb GIT binary patch literal 11280 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ⅈ#`_VC(zdU> z18bgIm3at)JDMJIi99QzFx-4d0LV)PBD0K zGG}CgN2VndlcFTcd=2w0U`c&84(~w31z??a?Me%dZq)od^PPLDStD5(46HeO?v5Mh zDh0t89f{>`q$N5Jg%D-Im-HZsGC`PetaXxqT&}M`zOcTtQ&u%6Jvzk6iGA8-T7sF#92M!aa;q&!9=D<}>Jg?R% z{io&4JF*|x7nz&iPxL?RGPyBxPW)409m?+l-$4JbDt`%>sltN&sj?ApNy3|A=gw?# zq&*!Q8#-_6QM=IH=|2!iuCu|rnmrCK0{AY1SK-zlJ;BqeZilDB5@wGL1W(n5Jv%gh ziTD|zB^Ubry}&97ivJSDJf@b>Tx+W+Gnz+Z&c>B2vFX3p|=822{(Y@9?k9`%EMoE(_HKg@0_ZJ7Jf{u_oL!ZHE#->}Sg{oaIV-ZR@{ z1?s*Bc`eV6)dSQ4vL^Ln$NnQBAbpWiUtn1g6t>8GV~!~NH_f&7`I1AB2>?lwHqRsiJ=b5in~?8!MeQhy_>S*Emu&qGPxy^{Gz zd9J$|SDIA>?Bw;po<%O0V19Yx+u=AckZ(xp2mny$90!-dQ>{~g0h#1X*u$0ivCeI@ z&v?b zd*CZ==dT`7h=)6`f13fGF6nsxnv8FO%`T1~=#;5?G7w{_Jh~tb;2HvM!5s3Z zn~q@vtX)O10W2bWtm*o!4wlMYoR7AS0R&5j*!dW756bSZvg-F-2zp4xpPC}898dcY z;2I#=$uVb;mpP&+|M@bJz(Dbb#SOQVGv9#BGe%kyb;vTZva*DxX-n8 zc)@)0%S3cyLdXG1=>*$C1oR^?H5yyfPvq=C;0mHH9o3LEzFcX^ACj5bKBvyoi*m)^ z;(xuISc4>(WhP{vM! zD;W7HOH7S8u%OI%PA??))dVe!Po9UmK)MQq`E8FJeqBBvt%^IQ+f|2)dhH6Z!xR{M zo^$-9G*S;?J(b6R?7dR=n#+UsVvemhVamu-78N&#@pTC9$`1Mz>3~CDNxWh@2lKap zL*-nEFJ&EX3Q(_zOw^Q2t<=ESqf**TMTiy_^h>R)pAQWO&7u>FS7V)O-etsrE?f~a z7;@I2;*2{%|+cu8gb5yKeKi;u=;&; z*Npg|rN|54MGbgydL=vc*#sc_mSbvra-U7+HLK$XtJpH`;0@*C>ABpw2DygLV~Wp+ zFxNd-S`Q`-<}8~nNc)NrOUmI8{p$TvVyu+Vi^3N!M6EL`j`YN!+YWyW&6 zk5DWg_O zO^|mDOX-a&c+L?-&sW#!YWhdskjXHF3!v(@!jcd4$JD87iySVf+pXS~KWTG%YVB^a}uNr(S)NX!nQcc1oq?}Kr%0aT#U6v6p z#xU#7demAHCb#=cw2E!CN5>h!mb{lz1~w+1<|YE>QuqCQrSn)n_s8Ppt$_}3G_)xD zUPsf%>lD2h(SX{~KrIoy%kLvmit^eSD)Zg=nF`#r^WqEST-8c-9|!aG>x|14qgvyN z&j*9vm=!u@&UMh1oI);ktCi8)b8e4cqut4cXt`_^M3r`1Y4Ob#8FPNRptYF%s92w# zeTl5A00+&3@$qAU3chQ5@)QcV%LQ5IaFgF zB+gYPw5tI8wOJmgTx4b1a*iT_LS?_4cqXFcPBRkk2ivCOa=|Yro@k9E5rQnApUM(& za&_r`Iovl9z@vwOO#(;Cqq=g-t1%D~>1l)vo)nvtAb5)`TAgl;Oc-_|i(V95wkV)E zA#7c8iu+9l=cuv_~_h!)o+8!LKmXA$0n;6#N-QA`s0#b;I$8r zs}isenvFFu-@`r@;jxxO4RuVvj}<5E@m_^eI}z04wp7^6CD76*5)ZTHnqD?#G= zsX=ehU=7>oHYL-3cUK1zxcXKe_@!$OOg#^RmI{-6{#$Z!_U}yOSE2tkYhwQWjqte* zmERGe|AO26hG+eM$=E5D3{MU5Kb@a_dN>n$o)$T{L*sjW*vCC?nuNNK0sp=4!3H?5 ZgqaJTKNDtH&%*qyr+rDQP}A=2{{x2KQPKba diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -9,15 +9,27 @@ .. versionadded:: 3.4 - This module offers classes representing filesystem paths with semantics appropriate for different operating systems. Path classes are divided between :ref:`pure paths `, which provide purely computational operations without I/O, and :ref:`concrete paths `, which inherit from pure paths but also provide I/O operations. -The main point of entry is the :class:`Path` class, which will instantiate -a :ref:`concrete path ` for the current platform. +.. image:: pathlib-inheritance.png + :align: center + +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 ` 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. .. note:: This module has been included in the standard library on a @@ -86,8 +98,57 @@ access a filesystem. There are three ways to access these classes, which we also call *flavours*: +.. class:: PurePath(*pathsegments) -.. class:: PurePosixPath + 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 or bytes object + representing a path segment; it can also be 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('.') + + When several absolute paths are given, the last is taken as an anchor + (mimicking :func:`os.path.join`'s behaviour):: + + >>> PurePath('/etc', '/usr', 'lib64') + PurePosixPath('/usr/lib64') + >>> PureWindowsPath('c:/Windows', 'd:bar') + PureWindowsPath('d:bar') + + However, in a Windows path, changing the local root doesn't discard the + previous drive setting:: + + >>> PureWindowsPath('c:/Windows', '/Program Files') + PureWindowsPath('c:/Program Files') + + Spurious slashes and single dots are collapsed, but double dots (``'..'``) + are not, since this would change the meaning of a path in the face of + symbolic links:: + + >>> 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) + +.. class:: PurePosixPath(*pathsegments) A subclass of :class:`PurePath`, this path flavour represents non-Windows filesystem paths:: @@ -95,7 +156,9 @@ >>> PurePosixPath('/etc') PurePosixPath('/etc') -.. class:: PureWindowsPath + *pathsegments* is specified similarly to :class:`PurePath`. + +.. class:: PureWindowsPath(*pathsegments) A subclass of :class:`PurePath`, this path flavour represents Windows filesystem paths:: @@ -103,67 +166,12 @@ >>> PureWindowsPath('c:/Program Files/') PureWindowsPath('c:/Program Files') -.. class:: PurePath - - A generic class that represents the system's path flavour (instantiating - it creates either a :class:`PurePosixPath` or a :class:`PureWindowsPath`):: - - >>> PurePath('setup.py') - PurePosixPath('setup.py') - + *pathsegments* is specified similarly to :class:`PurePath`. 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. -Constructing paths -^^^^^^^^^^^^^^^^^^ - -Path constructors accept an arbitrary number of positional arguments. -When called without any argument, a path object points to the current -directory:: - - >>> PurePath() - PurePosixPath('.') - -Any argument can be a string or bytes object representing an arbitrary number -of path segments, but it can also be another path object:: - - >>> PurePath('foo', 'some/path', 'bar') - PurePosixPath('foo/some/path/bar') - >>> PurePath(Path('foo'), Path('bar')) - PurePosixPath('foo/bar') - -When several absolute paths are given, the last is taken as an anchor -(mimicking :func:`os.path.join`'s behaviour):: - - >>> PurePath('/etc', '/usr', 'lib64') - PurePosixPath('/usr/lib64') - >>> PureWindowsPath('c:/Windows', 'd:bar') - PureWindowsPath('d:bar') - -However, in a Windows path, changing the local root doesn't discard the -previous drive setting:: - - >>> PureWindowsPath('c:/Windows', '/Program Files') - PureWindowsPath('c:/Program Files') - -Spurious slashes and single dots are collapsed, but double dots (``'..'``) -are not, since this would change the meaning of a path in the face of -symbolic links:: - - >>> 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) - - General properties ^^^^^^^^^^^^^^^^^^ @@ -524,24 +532,7 @@ 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:: PosixPath - - A subclass of :class:`Path` and :class:`PurePosixPath`, this class - represents concrete non-Windows filesystem paths:: - - >>> PosixPath('/etc') - PosixPath('/etc') - -.. class:: WindowsPath - - A subclass of :class:`Path` and :class:`PureWindowsPath`, this class - represents concrete Windows filesystem paths:: - - >>> WindowsPath('c:/Program Files/') - WindowsPath('c:/Program Files') - -.. class:: Path +.. class:: Path(*pathsegments) A subclass of :class:`PurePath`, this class represents concrete paths of the system's path flavour (instantiating it creates either a @@ -550,6 +541,27 @@ >>> 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') + PosixPath('/etc') + + *pathsegments* is specified similarly to :class:`PurePath`. + +.. class:: WindowsPath(*pathsegments) + + A subclass of :class:`Path` and :class:`PureWindowsPath`, this class + represents concrete Windows filesystem paths:: + + >>> WindowsPath('c:/Program Files/') + WindowsPath('c:/Program Files') + + *pathsegments* is specified similarly to :class:`PurePath`. You can only instantiate the class flavour that corresponds to your system (allowing system calls on non-compatible path flavours could lead to