Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vg.compat forward-compatibilty layer for libraries #158

Merged
merged 8 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 1 addition & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why drop all of this documentation from the README?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's duplicated from the documentation, and that seems like a better place for it: https://vgpy.dev/

Installation
------------

Expand All @@ -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
-----------

Expand All @@ -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
----------------

Expand Down
48 changes: 46 additions & 2 deletions doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 &ndash; 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 &hellip;
-------------------------------------------
Expand Down
Empty file added vg/compat/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions vg/compat/test_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import numpy as np
import pytest
import vg.compat.v1 as vg
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍



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)
)
1 change: 1 addition & 0 deletions vg/compat/v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from ..core import * # noqa: F401, F403