srctools.filesys

Implements a consistent interface for reading files.

This allows accessing different backing file sources interchangably. Files are case-insensitive, and both slashes are converted to ‘/’.

With a filesystem object, you can index it to locate files inside (raising FileNotFoundError if missing). Once a File object is obtained, call open_bin() or open_str() to read the contents. Writing is not supported.

  • FileSystem is the base ABC, which can be subclassed to define additional subsystems.

  • RawFileSystem provides access to a directory, optionally prohibiting access to parent folders.

  • ZipFileSystem and VPKFileSystem provide access to their respective archives.

  • VirtualFileSystem redirects to a mapping object, for fake file contents already in memory.

  • FileSystemChain contains multiple other systems, concatenating them together like how Source treats its search paths.

See the srctools.game.Game class for parsing gameinfo.txt files into filesystems. To mount a BSP file, use ZipFileSystem(bsp.pakfile).

exception srctools.filesys.RootEscapeError(root: str, path: str)

Raised when a path tries to refer to a file outside the root of a filesystem.

srctools.filesys.get_filesystem(
path: str,
) FileSystem[Any]

Return a filesystem given a path.

If the path is a directory this returns a RawFileSystem. Otherwise, it returns a VPK or zip, depending on extension.

srctools.filesys.CACHE_KEY_INVALID = -1

This is returned from FileSystem.cache_key() to indicate no key could be computed.

class srctools.filesys.FileSystem(path: str | _os.PathLike[str])

Base class for different systems defining the interface.

__init__(
path: str | _os.PathLike[str],
) None
__repr__() str

Return repr(self).

open_ref() None
Deprecated:

No longer needs to be called.

close_ref() None
Deprecated:

No longer needs to be called.

_check_open() None

Ensure self._ref is valid.

read_kv1(
path: str | File[Self],
encoding: str = 'utf8',
) Keyvalues

Read a Keyvalues1 file from the filesystem.

This handles opening and closing files.

read_prop(
path: str,
encoding: str = 'utf8',
) Keyvalues

Read a Keyvalues1 file from the filesystem.

Deprecated:

Use read_kv1().

__eq__(other: object) bool

Filesystems are equal if they have the same type and same path.

__hash__() int

Return hash(self).

__enter__() Self
Deprecated:

No longer needs to be used as a context manager.

__exit__(*args: object) None
Deprecated:

No longer needs to be used as a context manager.

__iter__() Iterator[File[Self]]

Iteration yields each file.

classmethod _get_data(
file: File[Self],
) _FileDataT

Accessor for file._data, to show the relationship to the type checker.

It should only be available to that filesystem, and produces the type.

_get_file(
name: str,
) File[Self]

Return a specific file.

walk_folder(
folder: str = '',
) Iterator[File[Self]]

Iterate over all files in the specified subfolder, yielding each.

open_str(
name: str | File[Self],
encoding: str = 'utf8',
) TextIO

Open a file in unicode mode or raise FileNotFoundError.

This should be closed when done.

open_bin(
name: str | File[Self],
) BinaryIO

Open a file in bytes mode or raise FileNotFoundError.

This should be closed when done.

_get_cache_key(
file: File[Self],
) int

Return a checksum or last-modified date suitable for caching.

This allows preventing reparsing the file. If not possible, return CACHE_KEY_INVALID (-1).

__weakref__

list of weak references to the object (if defined)

class srctools.filesys.File(
system: FileSysT_co,
path: str,
data: Any,
)

Represents a file in a system. Should only be created by filesystems.

__init__(
system: FileSysT_co,
path: str,
data: Any,
) None

Create a File.

Parameters:
  • system – should be the filesystem which matches.

  • path – is the relative path for the file.

  • data – is filesystem-specific data, allowing directly opening the file.

__fspath__() str

This can be interpreted as a path.

open_bin() BinaryIO

Return a file-like object in bytes mode.

This should be closed when done.

open_str(encoding: str = 'utf8') TextIO

Return a file-like object in unicode mode.

This should be closed when done.

cache_key() int

Return a checksum or last-modified date suitable for caching.

This allows preventing reparsing the file. If not possible, return -1.

__weakref__

list of weak references to the object (if defined)

Concrete implementations

class srctools.filesys.FileSystemChain(
*systems: FileSystem[Any] | Tuple[FileSystem[Any], str],
)

Chains several filesystem into one prioritised whole.

Each system can additionally be filtered to only allow access to files inside a subfolder. These will appear as if they are at the root level.

classmethod get_system(
file: File[Self],
) FileSystem[Any]

Retrieve the system for a File, if it was produced from a FileSystemChain.

add_sys(
sys: FileSystem[Any],
prefix: str = '',
*,
priority: bool = False,
) None

Add a filesystem to the list.

Parameters:
  • priority – If True, the system will be added to the start, instead of the end.

  • sys – The filesystem to add.

  • prefix – If specified, only this subfolder’s contents will be accessible, instead of the whole system.

open_str(
name: str | File[Self],
encoding: str = 'utf8',
) TextIO

Open a file in unicode mode or raise FileNotFoundError.

This should be closed when done.

open_bin(
name: str | File[Self],
) BinaryIO

Open a file in bytes mode or raise FileNotFoundError.

This should be closed when done.

walk_folder(
folder: str = '',
) Iterator[File[Self]]

Walk folders, not repeating files.

This requires temporarily storing the visited paths, to prevent revisiting them. If repeated access is not problematic, prefer walk_folder_repeat().

walk_folder_repeat(
folder: str = '',
) Iterator[File[Self]]

Walk folders, but allow repeating files.

If a file is contained in multiple systems, it will be yielded for each. The first is the highest-priority. Using this instead of walk_folder() is cheaper, since a set of visited files must be maintained.

class srctools.filesys.RawFileSystem(
path: str | _os.PathLike[str],
constrain_path: bool = True,
)

Accesses files in a real folder.

This can prohibit access to folders above the root.

walk_folder(
folder: str = '',
) Iterator[File[Self]]

Yield files in a folder.

open_str(
name: str | File[Self],
encoding: str = 'utf8',
) TextIO

Open a file in unicode mode or raise FileNotFoundError.

This should be closed when done.

open_bin(
name: str | File[Self],
) BinaryIO

Open a file in bytes mode or raise FileNotFoundError.

This should be closed when done.

class srctools.filesys.VirtualFileSystem(
mapping: Mapping[str, str | bytes | bytearray | memoryview],
encoding: str = 'utf8',
)

Access a dict as if it were a filesystem.

The dict should map file paths to either bytes or strings. The encoding arg specifies how text data is presented if open_bin() is called.

open_bin(
name: str | File[Self],
) BinaryIO

Return a bytes buffer for a ‘file’.

open_str(
name: str | File[Self],
encoding: str = 'utf8',
) TextIO

Return a string buffer for a ‘file’.

This performs universal newlines conversion. The encoding argument is ignored for files which are originally text.

walk_folder(
folder: str = '',
) Iterator[File[Self]]

Return all files that are ‘subfolders’ of the provided folder.

class srctools.filesys.ZipFileSystem(
path: str | _os.PathLike[str],
zipfile: ZipFile | None = None,
)

Accesses files in a zip file.

walk_folder(
folder: str = '',
) Iterator[File[Self]]

Yield files in a folder.

open_bin(
name: str | File[Self],
) BinaryIO

Open a file in bytes mode or raise FileNotFoundError.

The filesystem needs to be open while accessing this.

open_str(
name: str | File[Self],
encoding: str = 'utf8',
) TextIOWrapper

Open a file in unicode mode or raise FileNotFoundError.

The filesystem needs to be open while accessing this.

class srctools.filesys.VPKFileSystem(path: str | _os.PathLike[str])

Accesses files in a VPK file.

walk_folder(
folder: str = '',
) Iterator[File[Self]]

Yield files in a folder.

open_bin(
name: str | File[Self],
) BinaryIO

Open a file in bytes mode or raise FileNotFoundError.

open_str(
name: str | File[Self],
encoding: str = 'utf8',
) TextIO

Open a file in unicode mode or raise FileNotFoundError.