Source code for almanac.pages.page_path

from __future__ import annotations

from pathlib import PurePosixPath
from typing import Any, Tuple, Union

from ..errors import PathSyntaxError


[docs]class PagePath: """An encapsulation of an absolute pseudo-filesystem path.""" def __init__( self, path: PagePathLike ) -> None: candidate_path: str = str(path) self.__class__.assert_absolute_path(candidate_path) self._segments: Tuple[str, ...] = PurePosixPath(candidate_path).parts self._path: str = '/' + '/'.join(self._segments[1:]) self._parent_dirs = tuple( '/' + '/'.join(self._segments[1:i]) for i in range(1, len(self._segments)) )
[docs] @staticmethod def assert_absolute_path( path: PagePathLike ) -> None: """Assert that the specified path is absolut. Raises: :class:`PathSyntaxError`: If the path is not absolute. """ if not str(path).startswith('/'): raise PathSyntaxError('Not an absolute path', 0)
@property def path( self ) -> str: """The string path wrapped in this instance.""" return self._path @property def segments( self ) -> Tuple[str, ...]: """The path segments of this class. .. code-block:: python >>> from almanac import PagePath >>> PagePath('/a/b/c').segments ('/', 'a', 'b', 'c') >>> PagePath('/').segments ('/',) """ return self._segments @property def parent_dirs( self ) -> Tuple[str, ...]: """All parent directory paths of this path. .. code-block:: python >>> from almanac import PagePath >>> print('\\n'.join(PagePath('/a/b/c/d/e').parent_dirs)) / /a /a/b /a/b/c /a/b/c/d """ return self._parent_dirs def __contains__( self, path: PagePathLike ) -> bool: """Whether the :class:`PathLike` is contained in this instance.""" return str(path) in self._path def __eq__( self, other: Any ) -> bool: if isinstance(other, (str, PagePath,)): return self._path == str(other) return NotImplemented def __hash__( self ) -> int: return hash(self._path) def __str__( self ) -> str: return self._path def __repr__( self ) -> str: return f'<{self.__class__.__qualname__} [{str(self)}]>'
PagePathLike = Union[str, PagePath]