utils.py 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import types
  2. from pathlib import Path
  3. from typing import Any, _Final, _GenericAlias, get_origin # type: ignore [attr-defined]
  4. _PATH_TYPE_LABELS = {
  5. Path.is_dir: 'directory',
  6. Path.is_file: 'file',
  7. Path.is_mount: 'mount point',
  8. Path.is_symlink: 'symlink',
  9. Path.is_block_device: 'block device',
  10. Path.is_char_device: 'char device',
  11. Path.is_fifo: 'FIFO',
  12. Path.is_socket: 'socket',
  13. }
  14. def path_type_label(p: Path) -> str:
  15. """
  16. Find out what sort of thing a path is.
  17. """
  18. assert p.exists(), 'path does not exist'
  19. for method, name in _PATH_TYPE_LABELS.items():
  20. if method(p):
  21. return name
  22. return 'unknown' # pragma: no cover
  23. # TODO remove and replace usage by `isinstance(cls, type) and issubclass(cls, class_or_tuple)`
  24. # once we drop support for Python 3.10.
  25. def _lenient_issubclass(cls: Any, class_or_tuple: Any) -> bool: # pragma: no cover
  26. try:
  27. return isinstance(cls, type) and issubclass(cls, class_or_tuple)
  28. except TypeError:
  29. if get_origin(cls) is not None:
  30. # Up until Python 3.10, isinstance(<generic_alias>, type) is True
  31. # (e.g. list[int])
  32. return False
  33. raise
  34. _WithArgsTypes = (_GenericAlias, types.GenericAlias, types.UnionType)
  35. _typing_base: Any = _Final # pyright: ignore[reportAttributeAccessIssue]