Skip to content

Commit

Permalink
Merge 4c05e77 into 2f305b8
Browse files Browse the repository at this point in the history
  • Loading branch information
willmcgugan committed Aug 11, 2018
2 parents 2f305b8 + 4c05e77 commit 0ceb6ec
Show file tree
Hide file tree
Showing 16 changed files with 522 additions and 27 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [2.1.0] - Unreleased

### Added

- fs.glob support

## [2.0.27] - 2018-08-05

### Fixed
Expand Down Expand Up @@ -159,6 +165,7 @@ No changes, pushed wrong branch to PyPi.
## [2.0.8] - 2017-08-13

### Added

- Lstat info namespace
- Link info namespace
- FS.islink method
Expand Down
2 changes: 2 additions & 0 deletions docs/source/conf.py
Expand Up @@ -302,3 +302,5 @@

# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False

napoleon_include_special_with_doc = True
72 changes: 72 additions & 0 deletions docs/source/globbing.rst
@@ -0,0 +1,72 @@
.. _globbing:

Globbing
========

Globbing is the process of matching paths according to the rules used
by the Unix shell.

Generally speaking, you can think of a glob pattern as a path containing
one or more wildcard patterns, separated by forward slashes.


Matching Files and Directories
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In a glob pattern, A ``*`` means match anything text in a filename. A ``?``
matches any single character. A ``**`` matches any number of subdirectories,
making the glob *recusrive*. If the glob pattern ends in a ``/``, it will
only match directory paths, otherwise it will match files and directories.

.. note::
A recursive glob requires that PyFilesystem scan a lot of files,
and can potentially be slow for large (or network based) filesystems.

Here's a summary of glob patterns:

``*``
Matches all files in the current directory.
``*.py``
Matches all .py file in the current directory.
``*.py?``
Matches all .py files and .pyi, .pyc etc in the currenct directory.
``project/*.py``
Matches all .py files in a directory called ``project``.
``*/*.py``
Matches all .py files in any sub directory.
``**/*.py``
Recursively matches all .py files.
``**/.git/``
Recursively matches all the git directories.


Interface
~~~~~~~~~

PyFilesystem supports globbing via the ``glob`` attribute on every FS
instance, which is an instance of :class:`~fs.glob.BoundGlobber`. Here's
how you might use it to find all the Python files in your filesystem::

for match in my_fs.glob("**/*.py"):
print(f"{match.path} is {match.info.size} bytes long")

Calling ``.glob`` with a pattern will return an iterator of
:class:`~fs.glob.GlobMatch` named tuples for each matching file or
directory. A glob match contains two attributes; ``path`` which is the
full path in the filesystem, and ``info`` which is an
:class:`fs.info.Info` info object for the matched resource.


Batch Methods
~~~~~~~~~~~~~

In addition to iterating over the results, you can also call methods on
the :class:`~fs.glob.Globber` which apply to every matched path.

For instance, here is how you can use glob to remove all ``.pyc`` files
from a project directory::

>>> import fs
>>> fs.open_fs('~/projects/my_project').glob('**/*.pyc').remove()
29

14 changes: 14 additions & 0 deletions docs/source/guide.rst
Expand Up @@ -196,6 +196,20 @@ The ``walk`` attribute on FS objects is instance of a :class:`~fs.walk.BoundWalk

See :ref:`walking` for more information on walking directories.

Globbing
~~~~~~~~

Closely related to walking a filesystem is *globbing*, which is a slightly higher level way of scanning filesystems. Paths can be filtered by a *glob* pattern, which is similar to a wildcard (such as ``*.py``), but can match multiple levels of a directory structure.

Here's an example of globbing, which removes all the ``.pyc`` files in your project directory::

>>> from fs import open_fs
>>> open_fs('~/project').glob('**/*.pyc').remove()
62

See :ref:`globbing` for more information.


Moving and Copying
~~~~~~~~~~~~~~~~~~

Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Expand Up @@ -17,6 +17,7 @@ Contents:
info.rst
openers.rst
walking.rst
globbing.rst
builtin.rst
implementers.rst
extension.rst
Expand Down
1 change: 1 addition & 0 deletions docs/source/reference.rst
Expand Up @@ -9,6 +9,7 @@ Reference
reference/copy.rst
reference/enums.rst
reference/errors.rst
reference/glob.rst
reference/info_objects.rst
reference/filesize.rst
reference/mirror.rst
Expand Down
5 changes: 5 additions & 0 deletions docs/source/reference/glob.rst
@@ -0,0 +1,5 @@
fs.glob
=======

.. automodule:: fs.glob
:members:
2 changes: 1 addition & 1 deletion fs/_version.py
@@ -1,3 +1,3 @@
"""Version, used in module and setup.py.
"""
__version__ = "2.0.27"
__version__ = "2.1.0"
29 changes: 12 additions & 17 deletions fs/base.py
Expand Up @@ -6,34 +6,23 @@
"""

from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import absolute_import, print_function, unicode_literals

import abc
import itertools
import os
import threading
import time
import typing
from functools import partial

from contextlib import closing
import itertools
from functools import partial

import six

from . import copy
from . import errors
from . import fsencode
from . import iotools
from . import move
from . import tools
from . import walk
from . import wildcard
from . import copy, errors, fsencode, iotools, move, tools, walk, wildcard
from .glob import BoundGlobber
from .mode import validate_open_mode
from .path import abspath
from .path import join
from .path import normpath
from .path import abspath, join, normpath
from .time import datetime_to_epoch
from .walk import Walker

Expand Down Expand Up @@ -108,6 +97,12 @@ def __exit__(
"""
self.close()

@property
def glob(self):
"""`~fs.glob.BoundGlobber`: a globber object..
"""
return BoundGlobber(self)

@property
def walk(self):
# type: (_F) -> BoundWalker[_F]
Expand Down

0 comments on commit 0ceb6ec

Please sign in to comment.