Paths, files and directories

xal provides interface to manage files and directories.

Tip

xal‘s path API is widely inspired by pathlib, which is Python’s standard API to manage paths. See also differences with pathlib section.

Use path interface

Let’s consider a xal session:

>>> import xal
>>> session = xal.LocalSession()
>>> session.client.connect()
True

Path API is registered as path in xal‘s builtin Sessions:

>>> session.path  
<xal.path.local.LocalPathProvider object at 0x...>

PathProvider API

Here are details about xal‘s path interface.

Path resource factory

The path interface can be used as a factory to create Path resources:

>>> path = session.path('tests/fixtures')
>>> path
Path('tests/fixtures')

See section about path objects below for details about Path instances.

cd(path)

Changes working directory.

It can be used as a context manager:

>>> former_path = session.path.cwd()
>>> with session.path.cd('tests') as new_path:
...     session.path.cwd() == new_path
True
>>> session.path.cwd() == former_path
True

Or standalone:

>>> former_path = session.path.cwd()
>>> session.path.cd('tests')  
Path('/.../tests')

Accepts text or path objects:

>>> session.path.cd(former_path)  
Path('/...')

Note

Path instances also have a cd() method.

sep

This is an equivalent of os.path.sep for current session.

In local session, it is obviously the same value as os.path.sep:

>>> import os
>>> session.path.sep == os.path.sep
True

pure_path(path)

Returns Path instance not related to session. It may be useful in some situations where you need to compare paths on pure path only.

>>> session.path('foo').xal_session is session
True
>>> session.path.pure_path('foo').xal_session is None
True

Path objects

The path interface can be used as a factory to create Path resources:

>>> path = session.path('tests/fixtures')
>>> path
Path('tests/fixtures')
>>> print path
tests/fixtures

Paths can be constructed with anything that can be converted to text, including path objects themselves:

>>> session.path(session.path('foo'))
Path('foo')

Pure paths VS concrete paths

As in pathlib, there is a difference between “pure paths” and “concrete paths”:

  • “pure paths” are the ones that are not attached to a session:

    >>> path = session.path.pure_path('foo')
    >>> path.xal_session is None
    True
    
  • “concrete paths” are the ones attached to a session.

    >>> path = session.path('foo')
    >>> path.xal_session is session
    True
    

Comparison

Pure paths are compared with respect to pure path only, even when compared to concrete paths:

>>> session.path.pure_path('foo') == session.path.pure_path('foo')
True
>>> session.path.pure_path('foo') == session.path('foo')
True

Concrete paths are compared with respect to session:

>>> session.path('foo') == session.path('foo')
True
>>> remote_session = xal.FabricSession()
>>> session.path('foo') == remote_session.path('foo')
False

Concatenation

Use slash (division) operator / to concatenate paths:

>>> session.path('foo') / session.path('bar')
Path('foo/bar')

Properties

Path instances have the same properties as pathlib‘s pure paths:

>>> path = session.path('/home/user/hello.txt.cpold')
>>> path.drive
''
>>> path.root
'/'
>>> path.anchor
'/'
>>> path.parents
(Path('/home/user'), Path('/home'), Path('/'))
>>> path.parent
Path('/home/user')
>>> path.name
'hello.txt.cpold'
>>> path.suffix
'.cpold'
>>> path.suffixes
['.txt', '.cpold']
>>> path.stem
'hello.txt'

Methods

Path instances have methods like pathlib.PurePath:

  • as_posix()
  • as_uri()
  • is_absolute()
  • is_reserved()
  • joinpath(*other)
  • match(pattern)
  • relative_to(other)
  • with_name(name)
  • with_suffix(suffix)

And methods like like pathlib.Path:

  • stat()
  • chmod(mode)
  • exists()
  • glob(pattern)
  • group()
  • is_dir()
  • is_file()
  • is_symlink()
  • is_socket()
  • is_fifo()
  • is_block_device()
  • is_char_device()
  • iterdir()
  • lchmod()
  • lstat()
  • mkdir(mode=0o777, parents=False)
  • open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
  • owner()
  • rename() and replace()
  • resolve()
  • rglob(pattern)
  • rmdir()
  • symlink_to(target, target_is_directory=False)
  • touch(mode=0o777, exist_ok=True)
  • unlink()

Differences with pathlib

Path constructor accepts a single argument

pathlib.Path accepts multiple positional arguments. In xal, only one is accepted. This limitation eases implementation on pure paths (without a session).

cwd()

pathlib implements cwd() as a class-level method of Path. In xal, it is a method of the instance of provider API, generally session.path.cwd().

resolve() works with non-existent files

pathlib.Path.resolve() raises OSError when called on a non-existent file or directory. In case of non existent file, xal‘s resolve() returns absolute path to file.

touch() returns Path instance

pathlib.Path.touch() returns None, whereas xal’s Path.touch() returns Path instance, so that calls can be chained.