You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It's important to realize that the status functions accepted both
45
-
tuples/lists of the correct length, and ``NDArray``'s of the correct shape.
46
-
If they only accepted ``NDArray``'s, we would use their ``Internal`` counterparts:
47
-
:class:`~.typing.InternalPoint2D`, :class:`~.typing.InternalPoint3D`, :class:`~.typing.InternalPoint2D_Array` and :class:`~.typing.InternalPoint3D_Array`.
48
-
49
-
In general, the type aliases prefixed with ``Internal`` should never be used on
50
-
user-facing classes and functions, but should be reserved for internal behavior.
41
+
# it's a Point3DLike
42
+
print_point3D(coord)
43
+
44
+
defshift_point_up(coord: Point3DLike) -> Point3D:
45
+
result = np.asarray(coord)
46
+
result +=UP
47
+
print(f"New point: {result}")
48
+
return result
49
+
50
+
Notice that the last function, ``shift_point_up()``, accepts a
51
+
:class:`~.Point3DLike` as a parameter and returns a :class:`~.Point3D`. A
52
+
:class:`~.Point3D` always represents a NumPy array consisting of 3 floats,
53
+
whereas a :class:`~.Point3DLike` can represent anything resembling a 3D point:
54
+
either a NumPy array or a tuple/list of 3 floats, hence the ``Like`` word. The
55
+
same happens with :class:`~.Point2D`, :class:`~.Point2D_Array` and
56
+
:class:`~.Point3D_Array`, and their ``Like`` counterparts
57
+
:class:`~.Point2DLike`, :class:`~.Point2DLike_Array` and
58
+
:class:`~.Point3DLike_Array`.
59
+
60
+
The rule for typing functions is: **make parameter types as broad as possible,
61
+
and return types as specific as possible.** Therefore, for functions which are
62
+
intended to be called by users, **we should always, if possible, accept**
63
+
``Like`` **types as parameters and return NumPy, non-** ``Like`` **types.** The
64
+
main reason is to be more flexible with users who might want to pass tuples or
65
+
lists as arguments rather than NumPy arrays, because it's more convenient. The
66
+
last function, ``shift_point_up()``, is an example of it.
67
+
68
+
Internal functions which are *not* meant to be called by users may accept
69
+
non-``Like`` parameters if necessary.
51
70
52
71
Vectors
53
72
~~~~~~~
@@ -61,20 +80,19 @@ consider this slightly contrived function:
61
80
defshift_mobject(mob: M, direction: Vector3D, scale_factor: float=1) -> M:
62
81
return mob.shift(direction * scale_factor)
63
82
64
-
Here we see an important example of the difference. ``direction`` can not, and
65
-
should not, be typed as a :class:`~.typing.Point3D` because the function does not accept tuples/lists,
66
-
like ``direction=(0, 1, 0)``. You could type it as :class:`~.typing.InternalPoint3D` and
67
-
the type checker and linter would be happy; however, this makes the code harder
68
-
to understand.
83
+
Here we see an important example of the difference. ``direction`` should not be
84
+
typed as a :class:`~.Point3D`, because it represents a direction along
85
+
which to shift a :class:`~.Mobject`, not a position in space.
69
86
70
87
As a general rule, if a parameter is called ``direction`` or ``axis``,
71
88
it should be type hinted as some form of :class:`~.VectorND`.
72
89
73
90
.. warning::
74
91
75
92
This is not always true. For example, as of Manim 0.18.0, the direction
76
-
parameter of the :class:`.Vector` Mobject should be ``Point2D | Point3D``,
77
-
as it can also accept ``tuple[float, float]`` and ``tuple[float, float, float]``.
93
+
parameter of the :class:`.Vector` Mobject should be
94
+
``Point2DLike | Point3DLike``, as it can also accept ``tuple[float, float]``
0 commit comments