diff --git a/README.md b/README.md index 37a6e9c..90d2ebf 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A **v**ery **g**ood vector-geometry toolbelt for dealing with 3D points and vectors. These are simple [NumPy][] operations made readable, built to scale from prototyping to production. -See the complete API reference: https://vgpy.readthedocs.io/en/latest/ +:book: See the complete documentation: https://vgpy.readthedocs.io/en/latest/ [pypi]: https://pypi.org/project/vg/ [coverage]: https://github.com/lace/vg/blob/master/.coveragerc @@ -70,14 +70,6 @@ angles = np.arccos(np.clip(cosines, -1.0, 1.0)) angles = vg.angle(v1s, v2s) ``` -Features --------- - -All functions are optionally vectorized, meaning they accept single inputs and -stacks of inputs interchangeably. They return The Right Thing – a single -result or a stack of results – without the need to reshape inputs or outputs. -With the power of NumPy, the vectorized functions are fast. - Installation ------------ @@ -100,32 +92,6 @@ projected = vg.scalar_projection( ``` -Design principles ------------------ - -Linear algebra is useful and it doesn't have to be dificult to use. With the -power of abstractions, simple operations can be made simple, without poring -through lecture slides, textbooks, inscrutable Stack Overflow answers, or -dense NumPy docs. Code that uses linear algebra and geometric transformation -should be readable like English, without compromising efficiency. - -These common operations should be abstracted for a few reasons: - -1. If a developer is not programming linalg every day, they might forget the - underlying formula. These forms are easier to remember and more easily - referenced. - -2. These forms tend to be self-documenting in a way that the NumPy forms are - not. If a developer is not programming linalg every day, this will again - come in handy. - -3. These implementations are more robust. They automatically inspect `ndim` - on their arguments, so they work equally well if the argument is a vector - or a stack of vectors. They are more careful about checking edge cases - like a zero norm or zero cross product and returning a correct result - or raising an appropriate error. - - Development ----------- @@ -135,14 +101,6 @@ environment with the project's dependencies. Subsequently, run `./dev.py install` to update the dependencies. -Versioning ----------- - -This library adheres to [Semantic Versioning][semver]. - -[semver]: https://semver.org/ - - Acknowledgements ---------------- diff --git a/doc/index.md b/doc/index.md index 94503b2..84d8292 100644 --- a/doc/index.md +++ b/doc/index.md @@ -112,13 +112,57 @@ These common operations should be abstracted for a few reasons: or raising an appropriate error. -Versioning ----------- +Future-proofing your application or library +------------------------------------------- This library adheres to [Semantic Versioning][semver]. [semver]: https://semver.org/ +Since Python can accommodate only one installation of a package, using a +toolbelt like `vg` as a transitive dependency can be a particular challenge, as +various dependencies in the tree may rely on different versions of vg. + +One option would be to avoid making breaking changes forevever. However this is +antithetical to one of the goals of the project, which is to make a friendly +interface for doing linear algebra. Experience has shown that over the years, +we get clearer about what does and doesn't belong in this library, and what ways +of exposing this functionality are easiest to learn. We want to continue to +improve the interface over time, even if it means small breaking changes. + +As a result, we provide a forward compatibility layer, which all libraries +depending on `vg` are encouraged to use. Replace `import vg` with +`from vg.compat import v1 as vg` and use `>=1.11` as your dependency specifier. +You can also replace 1.11 with a later version which includes a feature you +need. The important thing is not to use `>=1.11,<2`. Since this project +guarantees that `from vg.compat import v1 as vg` will continue to work the same +in 2.0+, the `<2` constraint provides no stability value – and it makes +things unnecessarily difficult for consumers who use multiple dependencies with +`vg`. + +Applications have two options: + +1. Follow the recommendation for libraries: specify `>=1.11` and import using + `from vg.compat import v1 as vg`. This option provides better code stability + and makes upgrades seamless. +2. Specify `>=1.11,<2` and use `import vg` directly, and when upgrading to + `>=2,<3`, review the changelog and modify the calling code if necessary. + This option ensures you stay up to date with the recommended, friendliest + interface for calling into `vg`. + +### Breaking changes + +The project's goal is to limit breaking changes to the API to every one to two +years. This means breaking changes must be batched. Typically such features are +first made available under the `vg.experimental` module, and then moved into +`vg` upon the next major version release. Such experimental features may change +in any subsequent minor release. + +### Deprecations + +Deprecated features will emit deprecation warnings in a minor version and cause +errors or incorrect behavior in the next major version. + If you like vg you might also like … ------------------------------------------- diff --git a/vg/compat/__init__.py b/vg/compat/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/vg/compat/test_v1.py b/vg/compat/test_v1.py new file mode 100644 index 0000000..d22eb4e --- /dev/null +++ b/vg/compat/test_v1.py @@ -0,0 +1,21 @@ +import numpy as np +import pytest +import vg.compat.v1 as vg + + +def test_v1_has_functions(): + np.testing.assert_array_equal( + vg.normalize(np.array([5, 0, 0])), np.array([1, 0, 0]) + ) + + +def test_v1_has_constants(): + np.testing.assert_array_equal(vg.basis.x, np.array([1, 0, 0])) + + +def test_v1_orient_is_alias_for_aligned_with(): + v1 = np.array([1.0, 2.0, 3.0]) + with pytest.deprecated_call(): + np.testing.assert_array_equal( + vg.orient(v1, along=vg.basis.z), vg.aligned_with(v1, along=vg.basis.z) + ) diff --git a/vg/compat/v1.py b/vg/compat/v1.py new file mode 100644 index 0000000..31d9d3e --- /dev/null +++ b/vg/compat/v1.py @@ -0,0 +1 @@ +from ..core import * # noqa: F401, F403