Previously it was possible to construct a sf.V2 with sf.V3(sf.V2()).
Not only is this confusing, but it can also be used to trick the type
checker into thinking a matrix is of a type it is not (for example, mypy
assumes sf.V3(sf.V2()) is a sf.V3).
An example where this change is useful is, for a = sf.M23() and
b = sf.M34(), sf.M24(a * b). This is because mypy cannot tell that
a * b has type sf.M24. With this change, not only does wrapping the
expression in sf.M24 communicate this fact to mypy, but it also
performs a runtime check that it does in fact have correct shape.
In matrix.py, had to change several methods to use Matrix instead of
self.__class__ or cls to construct a new matrix object when the new
matrix was not guarenteed to have the same shape.
Previously it was possible to construct a
sf.V2
withsf.V3(sf.V2())
. Not only is this confusing, but it can also be used to trick the type checker into thinking a matrix is of a type it is not (for example, mypy assumessf.V3(sf.V2())
is asf.V3
).An example where this change is useful is, for
a = sf.M23()
andb = sf.M34()
,sf.M24(a * b)
. This is because mypy cannot tell thata * b
has typesf.M24
. With this change, not only does wrapping the expression insf.M24
communicate this fact to mypy, but it also performs a runtime check that it does in fact have correct shape.In
matrix.py
, had to change several methods to useMatrix
instead ofself.__class__
orcls
to construct a new matrix object when the new matrix was not guarenteed to have the same shape.Topic: check_shape_copy_construct