Skip to content

Commit ab15ba7

Browse files
committed
docs
1 parent 7193cd4 commit ab15ba7

File tree

15 files changed

+218
-176
lines changed

15 files changed

+218
-176
lines changed

docs/source/guide.rst

+29-28
Original file line numberDiff line numberDiff line change
@@ -57,33 +57,33 @@ The opener system is particularly useful when you want to store the physical loc
5757
If you don't specify the protocol in the FS URL, then PyFilesystem will assume you want a OSFS relative from the current working directory. So the following would be an equivalent way of opening your home directory::
5858

5959
>>> from fs import open_fs
60-
>>> home_fs = open_fs('~/')
60+
>>> home_fs = open_fs('.')
6161
>>> home_fs.listdir('/')
6262
['world domination.doc', 'paella-recipe.txt', 'jokes.txt', 'projects']
6363

64-
Tree
65-
%%%%
64+
Tree Printing
65+
~~~~~~~~~~~~~
6666

6767
Calling :meth:`fs.base.FS.tree` on a FS object will print an ascii tree view of your filesystem. Here's an example::
6868

6969
>>> from fs import open_fs
7070
>>> my_fs = open_fs('.')
7171
>>> my_fs.tree()
7272
├── locale
73-
── readme.txt
73+
── readme.txt
7474
├── logic
7575
│ ├── content.xml
7676
│ ├── data.xml
7777
│ ├── mountpoints.xml
78-
── readme.txt
78+
── readme.txt
7979
├── lib.ini
80-
── readme.txt
80+
── readme.txt
8181

8282
This can be a useful debugging aid!
8383

8484

85-
Closing Filesystems
86-
~~~~~~~~~~~~~~~~~~~
85+
Closing
86+
~~~~~~~
8787

8888
FS objects have a :meth:`fs.base.FS.close` methd which will perform any required clean-up actions. For many filesystems (notably :class:`fs.osfs.OSFS`), the ``close`` method does very little. Other filesystems may only finalize files or release resources once ``close()`` is called.
8989

@@ -124,11 +124,11 @@ Info objects have a number of advantages over just a filename. For instance you
124124
Additionally, FS objects have a :meth:`fs.base.FS.filterdir` method which extends ``scandir`` with the ability to filter directory contents by wildcard(s). Here's how you might find all the Python files in a directory:
125125

126126
>>> code_fs = OSFS('~/projects/src')
127-
>>> directory = list(code_fs.filterdir('/', wildcards=['*.py']))
127+
>>> directory = list(code_fs.filterdir('/', files=['*.py']))
128128

129129
By default, the resource information objects returned by ``scandir`` and ``listdir`` will contain only the file name and the ``is_dir`` flag. You can request additional information with the ``namespaces`` parameter. Here's how you can request additional details (such as file size and file modified times)::
130130

131-
>>> directory = code_fs.filterdir('/', wildcards=['*.py'], namespaces=['details'])
131+
>>> directory = code_fs.filterdir('/', files=['*.py'], namespaces=['details'])
132132

133133
This will add a ``size`` and ``modified`` property (and others) to the resource info objects. Which makes code such as this work::
134134

@@ -164,22 +164,6 @@ The :class:`fs.base.FS.makedir` and :class:`fs.base.FS.makedirs` methods also re
164164

165165
Working with ``SubFS`` objects means that you can generally avoid writing much path manipulation code, which tends to be error prone.
166166

167-
Walking
168-
~~~~~~~
169-
170-
Often you will need to scan the files in a given directory, and any sub-directories. This is known as *walking* the filesystem.
171-
172-
Here's how you would print the paths to all your Python files in your home directory::
173-
174-
>>> from fs import open_fs
175-
>>> home_fs = open_fs('~/')
176-
>>> for path in home_fs.walk.files(wildcards=['*.py']):
177-
... print(path)
178-
179-
The ``walk`` attribute on FS objects is instance of a :class:`fs.walk.BoundWalker`, which should be able to handle most directory walking requirements.
180-
181-
See :ref:`walking` for more information on walking directories.
182-
183167
Working with Files
184168
~~~~~~~~~~~~~~~~~~
185169

@@ -192,10 +176,26 @@ You can open a file from a FS object with :meth:`fs.base.FS.open`, which is very
192176

193177
In the case of a ``OSFS``, a standard file-like object will be returned. Other filesystems may return a different object supporting the same methods. For instance, :class:`fs.memoryfs.MemoryFS` will return a ``io.BytesIO`` object.
194178

195-
PyFilesystem also offers a number of shortcuts for common file related operations. For example, :meth:`fs.base.FS.getbytes` will return the file contents as a bytes, and :meth:`fs.base.FS.gettext` will read unicode text. Using these methods is generally preferable to explicitly opening files, as the FS object may have an optimized implementation.
179+
PyFilesystem also offers a number of shortcuts for common file related operations. For instance, :meth:`fs.base.FS.getbytes` will return the file contents as a bytes, and :meth:`fs.base.FS.gettext` will read unicode text. These methods is generally preferable to explicitly opening files, as the FS object may have an optimized implementation.
196180

197181
Other *shortcut* methods are :meth:`fs.base.FS.setbin`, :meth:`fs.base.FS.setbytes`, :meth:`fs.base.FS.settext`.
198182

183+
Walking
184+
~~~~~~~
185+
186+
Often you will need to scan the files in a given directory, and any sub-directories. This is known as *walking* the filesystem.
187+
188+
Here's how you would print the paths to all your Python files in your home directory::
189+
190+
>>> from fs import open_fs
191+
>>> home_fs = open_fs('~/')
192+
>>> for path in home_fs.walk.files(filter=['*.py']):
193+
... print(path)
194+
195+
The ``walk`` attribute on FS objects is instance of a :class:`fs.walk.BoundWalker`, which should be able to handle most directory walking requirements.
196+
197+
See :ref:`walking` for more information on walking directories.
198+
199199
Moving and Copying
200200
~~~~~~~~~~~~~~~~~~
201201

@@ -219,5 +219,6 @@ The :func:`fs.copy.copy_fs` and :func:`fs.copy.copy_dir` functions also accept a
219219

220220
>>> from fs.copy import copy_fs
221221
>>> from fs.walk import Walker
222-
>>> copy_fs('~/projects', 'zip://projects.zip', walker=Walker(wildcards=['*.py']))
222+
>>> copy_fs('~/projects', 'zip://projects.zip', walker=Walker(files=['*.py']))
223+
223224

docs/source/reference.rst

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ Reference
1414
reference/path.rst
1515
reference/tree.rst
1616
reference/walk.rst
17+
reference/wildcard.rst

docs/source/reference/tree.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
fs.tree
22
=======
33

4-
Render ASCII (or unicode) directory trees.
4+
Render a text tree view, with optional color in terminals.
55

66
.. automodule:: fs.tree
77
:members:

fs/base.py

+45-37
Original file line numberDiff line numberDiff line change
@@ -219,20 +219,23 @@ def close(self):
219219
"""
220220
self._closed = True
221221

222-
def copy(self, src_path, dst_path):
222+
def copy(self, src_path, dst_path, overwrite=False):
223223
"""
224224
Copy file contents from ``src_path`` to ``dst_path``.
225225
226226
:param src_path: Path of source file.
227227
:type src_path: str
228228
:param dst_path: Path to destination file.
229229
:type dst_path: str
230-
231-
If the path specified by ``dst_path`` exists, and is a file,
232-
it will first be truncated.
230+
:raises `fs.errors.DestinationExists`: If ``dst_path`` exists,
231+
and overwrite == ``False``.
232+
:raises `fs.errors.ResourceNotFound`: If a parent directory of
233+
``dst_path`` does not exist.
233234
234235
"""
235236
with self._lock:
237+
if not overwrite and self.exists(dst_path):
238+
raise errors.DestinationExists(dst_path)
236239
with closing(self.open(src_path, 'rb')) as read_file:
237240
self.setbin(dst_path, read_file)
238241

@@ -319,36 +322,36 @@ def filterdir(self,
319322
path,
320323
exclude_dirs=False,
321324
exclude_files=False,
322-
wildcards=None,
323-
dir_wildcards=None,
325+
files=None,
326+
dirs=None,
324327
namespaces=None,
325328
page=None):
326329
"""
327330
Get an iterator of resource info, filtered by wildcards.
328331
329-
This method enhances the :meth:`fs.base.FS.scandir` method with
330-
additional filtering functionality.
331-
332332
:param str path: A path to a directory on the filesystem.
333333
:param bool exclude_dirs: Exclude directories.
334334
:param bool exclude_files: Exclude files.
335-
:param wildcards: A list of unix shell-style wildcards to filter
336-
file names.
335+
:param files: A list of unix shell-style patterns to filter
336+
file names, e.g. ``['*.py']``.
337337
:type wildcards: list or None
338-
:param dir_wildcards: A list of unix shell-style wildcards to
338+
:param dirs: A list of unix shell-style wildcards to
339339
filter directory names.
340-
:type dir_wildcards: list or None
340+
:type dirs: list or None
341341
:param namespaces: A list of info namespaces to include in
342342
results.
343343
:type namespaces: list or None
344-
:param page: May be a tuple of (start, end) indexes to return an
345-
iterator of a subset of the resource info, or ``None`` to
346-
iterator the entire directory. Paging a directory scan may
347-
be necessary for very large directories.
344+
:param page: May be a tuple of ``(<start>, <end>)`` indexes to
345+
return an iterator of a subset of the resource info, or
346+
``None`` to iterator the entire directory. Paging a
347+
directory scan may be necessary for very large directories.
348348
:type page: tuple or None
349349
:return: An iterator of :class:`fs.info.Info` objects.
350350
:rtype: iterator
351351
352+
This method enhances the :meth:`fs.base.FS.scandir` method with
353+
additional filtering functionality.
354+
352355
"""
353356

354357
case_sensitive = self.getmeta().get('case_sensitive', True)
@@ -369,24 +372,24 @@ def filterdir(self,
369372
if info.is_dir
370373
)
371374

372-
if wildcards is not None:
373-
if isinstance(wildcards, six.text_type):
375+
if files is not None:
376+
if isinstance(files, six.text_type):
374377
raise ValueError(
375378
'wildcards must be a sequence, not a string'
376379
)
377-
match = wildcard.get_matcher(wildcards, case_sensitive)
380+
match = wildcard.get_matcher(files, case_sensitive)
378381
resources = (
379382
info
380383
for info in resources
381384
if info.is_dir or match(info.name)
382385
)
383386

384-
if dir_wildcards is not None:
385-
if isinstance(dir_wildcards, six.text_type):
387+
if dirs is not None:
388+
if isinstance(dirs, six.text_type):
386389
raise ValueError(
387390
'dir_wildcards must be a sequence, not a string'
388391
)
389-
match = wildcard.get_matcher(dir_wildcards, case_sensitive)
392+
match = wildcard.get_matcher(dirs, case_sensitive)
390393
resources = (
391394
info
392395
for info in resources
@@ -577,8 +580,8 @@ def geturl(self, path, purpose='download'):
577580
:param str purpose: A short string that indicates which URL to
578581
retrieve for the given path (if there is more than one). The
579582
default is `'download'`, which should return a URL that
580-
serves the file. See the filesystem documentation for
581-
information on what other URLs may be generated.
583+
serves the file. Other filesystems may support other values
584+
for ``purpose``.
582585
:returns: A URL.
583586
:rtype: str
584587
:raises `fs.errors.NoURL`: If the path does not map to a URL.
@@ -712,9 +715,8 @@ def makedirs(self, path, permissions=None, recreate=False):
712715
713716
:raises `fs.errors.DirectoryExists`: if the path is already
714717
a directory, and ``recreate`` is False.
715-
:raises `fs.errors.NotADirectory`: if one of the ancestors in
716-
the path isn't a directory.
717-
:raises `fs.errors.ResourceNotFound`: if the path is not found.
718+
:raises `fs.errors.DirectoryExpected`: if one of the ancestors
719+
in the path isn't a directory.
718720
719721
"""
720722
self.check()
@@ -742,6 +744,10 @@ def move(self,
742744
file will be written to.
743745
:param bool overwrite: If `True` destination path will be
744746
overwritten if it exists.
747+
:raises `fs.errors.DestinationExists`: If ``dst_path`` exists,
748+
and overwrite == ``False``.
749+
:raises `fs.errors.ResourceNotFound`: If a parent directory of
750+
``dst_path`` does not exist.
745751
746752
"""
747753

@@ -811,6 +817,8 @@ def opendir(self, path):
811817
:param str path: Path to a directory on the filesystem.
812818
:returns: A filesystem object representing a sub-directory.
813819
:rtype: :class:`fs.subfs.SubFS`
820+
:raises `fs.errors.DirectoryExpected`: If ``dst_path`` does not
821+
exist or is not a directory.
814822
815823
"""
816824
from .subfs import SubFS
@@ -850,10 +858,10 @@ def scandir(self, path, namespaces=None, page=None):
850858
851859
:param str path: A path on the filesystem
852860
:param list namespaces: A sequence of info namespaces.
853-
:param page: May be a tuple of (start, end) indexes to return an
854-
iterator of a subset of the resource info, or ``None`` to
855-
iterator the entire directory. Paging a directory scan may
856-
be necessary for very large directories.
861+
:param page: May be a tuple of ``(<start>, <end>)`` indexes to
862+
return an iterator of a subset of the resource info, or
863+
``None`` to iterator the entire directory. Paging a
864+
directory scan may be necessary for very large directories.
857865
:type page: tuple or None
858866
:rtype: iterator
859867
@@ -1128,11 +1136,11 @@ def check(self):
11281136
if self.isclosed():
11291137
raise errors.FilesystemClosed()
11301138

1131-
def match(self, wildcards, name):
1139+
def match(self, patterns, name):
11321140
"""
11331141
Check if a name matches any of a list of wildcards.
11341142
1135-
:param list wildcards: A list of wildcards, e.g. ``['*.py']``
1143+
:param list patterns: A list of patterns, e.g. ``['*.py']``
11361144
:param str name: A file or directory name (not a path)
11371145
:rtype: bool
11381146
@@ -1147,14 +1155,14 @@ def match(self, wildcards, name):
11471155
>>> home_fs.match(['*.jpg', '*.png'], 'foo.gif')
11481156
False
11491157
1150-
If ``wildcards`` is ``None``, or (``['*']``), then this method
1158+
If ``patterns`` is ``None``, or (``['*']``), then this method
11511159
will always return True.
11521160
11531161
"""
1154-
if wildcards is None:
1162+
if patterns is None:
11551163
return True
11561164
case_sensitive = self.getmeta().get('case_sensitive', True)
1157-
matcher = wildcard.get_matcher(wildcards, case_sensitive)
1165+
matcher = wildcard.get_matcher(patterns, case_sensitive)
11581166
return matcher(name)
11591167

11601168
def tree(self, **kwargs):

fs/copy.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ def copy_file(src_fs, src_path, dst_fs, dst_path):
3838
"""
3939
Copy a file from one filesystem to another.
4040
41+
If the destination exists, and is a file, it will be first
42+
truncated.
43+
4144
:param src_fs: Source filesystem.
4245
:type src_fs: FS URL or instance
4346
:param src_path: Path to a file on ``src_fs``.
@@ -52,7 +55,7 @@ def copy_file(src_fs, src_path, dst_fs, dst_path):
5255
with manage_fs(dst_fs, create=True) as dst_fs:
5356
if src_fs is dst_fs:
5457
# Same filesystem, so we can do a potentially optimized copy
55-
src_fs.copy(src_path, dst_path)
58+
src_fs.copy(src_path, dst_path, overwrite=True)
5659
else:
5760
# Standard copy
5861
with src_fs.lock(), dst_fs.lock():
@@ -93,7 +96,7 @@ def copy_dir(src_fs, src_path, dst_fs, dst_path, walker=None):
9396
:type src_path: str
9497
:param dst_fs: Destination filesystem.
9598
:type dst_fs: FS URL or instance
96-
:param dst_path: A path to a directory on ``dst_fs``.
99+
:param str dst_path: A path to a directory on ``dst_fs``.
97100
:param walker: A walker object that will be used to scan for files
98101
in ``src_fs``. Set this if you only want to consider a sub-set
99102
of the resources in ``src_fs``.

fs/errors.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
'CreateFailed',
2121
'DestinationExists',
2222
'DirectoryExists',
23+
'DirectoryExpected',
2324
'DirectoryNotEmpty',
24-
'FilesystemClosed',
2525
'FileExists',
26+
'FileExpected',
27+
'FilesystemClosed',
2628
'FSError',
2729
'IllegalBackReference',
2830
'InsufficientStorage',

fs/move.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def move_dir(src_fs, src_path, dst_fs, dst_path):
6161
:type src_path: str
6262
:param dst_fs: Destination filesystem.
6363
:type dst_fs: FS URL or instance
64-
:param dst_path: A path to a directory on ``dst_fs``.
64+
:param str dst_path: A path to a directory on ``dst_fs``.
6565
6666
"""
6767
with manage_fs(src_fs) as src_fs:

0 commit comments

Comments
 (0)