Concepts¶
The following describes some core concepts when working with PyFilesystem. If you are skimming this documentation, pay particular attention to the first section on paths.
Paths¶
With the possible exception of the constructor, all paths in a filesystem are PyFilesystem paths, which have the following properties:
- Paths are
str
type in Python3, andunicode
in Python2- Path components are separated by a forward slash (
/
)- Paths beginning with a
/
are absolute- Paths not beginning with a forward slash are relative
- A single dot (
.
) means ‘current directory’- A double dot (
..
) means ‘previous directory’
Note that paths used by the FS interface will use this format, but the
constructor may not. Notably the OSFS
constructor which
requires an OS path – the format of which is platform-dependent.
Note
There are many helpful functions for working with paths in the
path
module.
PyFilesystem paths are platform-independent, and will be automatically converted to the format expected by your operating system – so you won’t need to make any modifications to your filesystem code to make it run on other platforms.
System Paths¶
Not all Python modules can use file-like objects, especially those which
interface with C libraries. For these situations you will need to
retrieve the system path. You can do this with the
getsyspath()
method which converts a valid path in the
context of the FS object to an absolute path that would be understood by
your OS.
For example:
>>> from fs.osfs import OSFS
>>> home_fs = OSFS('~/')
>>> home_fs.getsyspath('test.txt')
'/home/will/test.txt'
Not all filesystems map to a system path (for example, files in a
MemoryFS
will only ever exists in memory).
If you call getsyspath
on a filesystem which doesn’t map to a system
path, it will raise a NoSysPath
exception. If you
prefer a look before you leap approach, you can check if a resource
has a system path by calling hassyspath()
Sandboxing¶
FS objects are not permitted to work with any files outside of their
root. If you attempt to open a file or directory outside the
filesystem instance (with a backref such as "../foo.txt"
), a
IllegalBackReference
exception will be thrown. This
ensures that any code using a FS object won’t be able to read or modify
anything you didn’t intend it to, thus limiting the scope of any bugs.
Unlike your OS, there is no concept of a current working directory in
PyFilesystem. If you want to work with a sub-directory of an FS object,
you can use the opendir()
method which returns another
FS object representing the contents of that sub-directory.
For example, consider the following directory structure. The directory
foo
contains two sub-directories; bar
and baz
:
--foo
|--bar
| |--readme.txt
| `--photo.jpg
`--baz
|--private.txt
`--dontopen.jpg
We can open the foo
directory with the following code:
from fs.osfs import OSFS
foo_fs = OSFS('foo')
The foo_fs
object can work with any of the contents of bar
and
baz
, which may not be desirable if we are passing foo_fs
to a
function that has the potential to delete files. Fortunately we can
isolate a single sub-directory with the opendir()
method:
bar_fs = foo_fs.opendir('bar')
This creates a completely new FS object that represents everything in
the foo/bar
directory. The root directory of bar_fs
has been re-
position, so that from bar_fs
’s point of view, the readme.txt and
photo.jpg files are in the root:
--bar
|--readme.txt
`--photo.jpg
Note
This sandboxing only works if your code uses the filesystem interface exclusively. It won’t prevent code using standard OS level file manipulation.