Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/fontTools/misc/vector.py: 48%

80 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:33 +0000

1from numbers import Number 

2import math 

3import operator 

4import warnings 

5 

6 

7__all__ = ["Vector"] 

8 

9 

10class Vector(tuple): 

11 

12 """A math-like vector. 

13 

14 Represents an n-dimensional numeric vector. ``Vector`` objects support 

15 vector addition and subtraction, scalar multiplication and division, 

16 negation, rounding, and comparison tests. 

17 """ 

18 

19 __slots__ = () 

20 

21 def __new__(cls, values, keep=False): 

22 if keep is not False: 

23 warnings.warn( 

24 "the 'keep' argument has been deprecated", 

25 DeprecationWarning, 

26 ) 

27 if type(values) == Vector: 

28 # No need to create a new object 

29 return values 

30 return super().__new__(cls, values) 

31 

32 def __repr__(self): 

33 return f"{self.__class__.__name__}({super().__repr__()})" 

34 

35 def _vectorOp(self, other, op): 

36 if isinstance(other, Vector): 

37 assert len(self) == len(other) 

38 return self.__class__(op(a, b) for a, b in zip(self, other)) 

39 if isinstance(other, Number): 

40 return self.__class__(op(v, other) for v in self) 

41 raise NotImplementedError() 

42 

43 def _scalarOp(self, other, op): 

44 if isinstance(other, Number): 

45 return self.__class__(op(v, other) for v in self) 

46 raise NotImplementedError() 

47 

48 def _unaryOp(self, op): 

49 return self.__class__(op(v) for v in self) 

50 

51 def __add__(self, other): 

52 return self._vectorOp(other, operator.add) 

53 

54 __radd__ = __add__ 

55 

56 def __sub__(self, other): 

57 return self._vectorOp(other, operator.sub) 

58 

59 def __rsub__(self, other): 

60 return self._vectorOp(other, _operator_rsub) 

61 

62 def __mul__(self, other): 

63 return self._scalarOp(other, operator.mul) 

64 

65 __rmul__ = __mul__ 

66 

67 def __truediv__(self, other): 

68 return self._scalarOp(other, operator.truediv) 

69 

70 def __rtruediv__(self, other): 

71 return self._scalarOp(other, _operator_rtruediv) 

72 

73 def __pos__(self): 

74 return self._unaryOp(operator.pos) 

75 

76 def __neg__(self): 

77 return self._unaryOp(operator.neg) 

78 

79 def __round__(self, *, round=round): 

80 return self._unaryOp(round) 

81 

82 def __eq__(self, other): 

83 if isinstance(other, list): 

84 # bw compat Vector([1, 2, 3]) == [1, 2, 3] 

85 other = tuple(other) 

86 return super().__eq__(other) 

87 

88 def __ne__(self, other): 

89 return not self.__eq__(other) 

90 

91 def __bool__(self): 

92 return any(self) 

93 

94 __nonzero__ = __bool__ 

95 

96 def __abs__(self): 

97 return math.sqrt(sum(x * x for x in self)) 

98 

99 def length(self): 

100 """Return the length of the vector. Equivalent to abs(vector).""" 

101 return abs(self) 

102 

103 def normalized(self): 

104 """Return the normalized vector of the vector.""" 

105 return self / abs(self) 

106 

107 def dot(self, other): 

108 """Performs vector dot product, returning the sum of 

109 ``a[0] * b[0], a[1] * b[1], ...``""" 

110 assert len(self) == len(other) 

111 return sum(a * b for a, b in zip(self, other)) 

112 

113 # Deprecated methods/properties 

114 

115 def toInt(self): 

116 warnings.warn( 

117 "the 'toInt' method has been deprecated, use round(vector) instead", 

118 DeprecationWarning, 

119 ) 

120 return self.__round__() 

121 

122 @property 

123 def values(self): 

124 warnings.warn( 

125 "the 'values' attribute has been deprecated, use " 

126 "the vector object itself instead", 

127 DeprecationWarning, 

128 ) 

129 return list(self) 

130 

131 @values.setter 

132 def values(self, values): 

133 raise AttributeError( 

134 "can't set attribute, the 'values' attribute has been deprecated", 

135 ) 

136 

137 

138def _operator_rsub(a, b): 

139 return operator.sub(b, a) 

140 

141 

142def _operator_rtruediv(a, b): 

143 return operator.truediv(b, a)