Coverage for trimesh/typed.py: 97%

29 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-24 04:40 +0000

1from collections.abc import Callable, Hashable, Iterable, Mapping, Sequence 

2from io import IOBase 

3from pathlib import Path 

4from sys import version_info 

5from typing import ( 

6 IO, 

7 Any, 

8 BinaryIO, 

9 Literal, 

10 Protocol, 

11 TypeAlias, 

12 TypeGuard, 

13 TypeVar, 

14 runtime_checkable, 

15) 

16 

17from numpy import dtype, float64, floating, generic, int64, integer, ndarray 

18from numpy.typing import ArrayLike, DTypeLike, NDArray 

19 

20if version_info >= (3, 11): 

21 from typing import Self 

22else: 

23 Self = Any 

24 

25# most loader routes take `file_obj` which can either be 

26# a file-like object or a file path, or sometimes a dict 

27# `IOBase` is the base of every stdlib stream and is included because 

28# concrete streams like `io.BytesIO` don't satisfy the `IO` protocol 

29# under beartype — https://github.com/beartype/beartype/issues/643 

30Stream: TypeAlias = IO[str] | IO[bytes] | IOBase 

31Loadable: TypeAlias = str | Path | Stream | dict | None 

32 

33# for a function that returns "is this a file or not" 

34# but with typeguard-narrowing if the answer is yes 

35BoolIsFile: TypeAlias = TypeGuard[IO[Any]] 

36 

37# numpy integers do not inherit from python integers, i.e. 

38# if you type a function argument as an `int` and then pass 

39# a value from a numpy array like `np.ones(10, dtype=np.int64)[0]` 

40# you may have a type error. 

41# these wrappers union numpy integers and python integers 

42Integer: TypeAlias = int | integer 

43 

44# Numbers which can only be floats and will not accept integers 

45# > isinstance(np.ones(1, dtype=np.float32)[0], floating) # True 

46# > isinstance(np.ones(1, dtype=np.float32)[0], float) # False 

47Floating: TypeAlias = float | floating 

48 

49# Many arguments take "any valid number" and don't care if it 

50# is an integer or a floating point input. 

51Number: TypeAlias = Floating | Integer 

52 

53# the literals for specifying what viewer to use 

54ViewerType: TypeAlias = Callable | Literal["gl", "jupyter", "marimo"] | None 

55 

56# literal for color maps we include in the library 

57ColorMapType: TypeAlias = Literal["viridis", "magma", "inferno", "plasma"] 

58 

59# the literal for what graph backend engines are available 

60GraphEngineType: TypeAlias = Literal["networkx", "scipy"] | None 

61 

62# what 3D boolean engines are available 

63BooleanEngineType: TypeAlias = Literal["manifold", "blender"] | None 

64# what 3D boolean operations can be passed to boolean functions 

65BooleanOperationType: TypeAlias = Literal["difference", "union", "intersection"] 

66 

67# what are the supported methods for converting a mesh into voxels. 

68VoxelizationMethodsType: TypeAlias = Literal["subdivide", "ray", "binvox"] 

69 

70 

71@runtime_checkable 

72class HttpSessionLike(Protocol): 

73 """ 

74 Structural type for an HTTP session. 

75 

76 Matches `httpx.Client` and `requests.Session` so a resolver 

77 can take either without trimesh importing them directly. 

78 """ 

79 

80 def get(self, url: str, *args, **kwargs) -> Any: ... 

81 

82 

83# add numpy types like their `numpy.typing.NDArray` 

84# but with specific dimensionality, i.e. `NDArray2D[np.float64]` 

85DType = TypeVar("DType", bound=generic) 

86NDArray1D: TypeAlias = ndarray[tuple[int], dtype[DType]] 

87NDArray2D: TypeAlias = ndarray[tuple[int, int], dtype[DType]] 

88NDArray3D: TypeAlias = ndarray[tuple[int, int, int], dtype[DType]] 

89 

90__all__ = [ 

91 "IO", 

92 "Any", 

93 "ArrayLike", 

94 "BinaryIO", 

95 "BoolIsFile", 

96 "Callable", 

97 "DTypeLike", 

98 "Floating", 

99 "Hashable", 

100 "HttpSessionLike", 

101 "Integer", 

102 "Iterable", 

103 "Loadable", 

104 "Mapping", 

105 "NDArray", 

106 "NDArray1D", 

107 "NDArray2D", 

108 "NDArray3D", 

109 "Number", 

110 "Self", 

111 "Sequence", 

112 "Stream", 

113 "ViewerType", 

114 "float64", 

115 "int64", 

116]