CHANGES
=======

3.0rc3 (2026-01-30)
-------------------

The single file module affine.py has been moved to affine/__init__.py so that
a py.typed file can be distributed in the same directory (#136).

3.0rc2 (2026-01-27)
-------------------

3.0rc1 tagged the wrong commit. The distributions on PyPI have the correct
version, but the GitHub release does not. This is fixed by 3.0rc2, which makes
no other changes.

3.0rc1 (2026-01-26)
-------------------

This is the first 3.0 release candidate. There are no significant changes
since 3.0b1.

3.0b1 (2025-01-29)
------------------

- Matrix multiplication with tuples of coordinate matrices, like the output of
  numpy.meshgrid(), has been restored (#126).

3.0a1 (2025-01-27)
------------------

- Type hint annotations for functions and methods are complete (#121).
- Affine raises ValueError if initialized with values for g, h, and i that are
  not 0.0, 0.0, and 1.0, respectively (#117).
- Python version support was changed to 3.9+ (#110).
- Switch from namedtuple to attrs for implementation of the Affine class and
  use functools.cached_property(), which absolutely requires Python 3.8+
  (#111).
- Source was moved to a single-module affine.py in the src directory (#112).
- Add numpy __array__ interface (#108).
- Add support for ``@`` matrix multiplier methods (#122).

2.4.0 (2023-01-19)
------------------

- Package is marked as Python 3 only, two instances of "%" string formatting
  are replaced by f-strings (#96).

2.4b1 (2023-01-18)
------------------

- Elimination of Python 2/3 compatibility code in __gt__ (#94).
- Addition of optional keyword arguments for __new__, solving an issue with
  Dask (#92).
- Addition of some type hints for float arguments and return types (#87).
- Python version support is now 3.7-3.11 (#82).
- Faster __new__ and from_gdal methods (#78).

2.3.1 (2022-03-24)
------------------

Bug fixes:

- Return NotImplemented for both ValueError and TypeError in __mul__ to support
  fallback to __rmul__ in more cases (gh-71).

2.3.0 (2019-09-04)
------------------

Deprecations:

- Right multiplication like vector * matrix is deprecated and will raise
  AffineError in version 3.0.0.

Bug fixes:

- Change signature of Affine constructor to help users of PyCharm (#45).
- The Affine class docstring has been improved.

2.2.2 (2018-12-20)
------------------
- Affine.itransform computed the wrong results for arrays with rotation or
  shear (#40). This is fixed (#41).

2.2.1 (2018-06-04)
------------------
- Docstring improvements (#37).

2.2.0 (2018-03-20)
------------------
- Addition of permutation matrix (#35).

2.1.0 (2017-07-12)
------------------
- Addition of new ``eccentricity`` and ``rotation_angle`` properties (#28).

2.0.0.post1 (2016-05-20)
------------------------
- This is the final 2.0.0 release. The post-release version segment is used
  because we accidentally uploaded a 2.0.0 to PyPI before the beta releases
  below.

2.0b2 (2016-05-16)
------------------
- Bug fix: restore ``Affine __rmul__`` even though it permits dubious
  vector * matrix expressions (#27).

2.0b1 (2016-05-16)
------------------
- Breaking change: precision used in properties like ``is_conformal`` is no
  longer a global module attribute, but an Affine class or instance attribute
  (#19, #20).
- Breaking change: ``is_degenerate`` property is now exact and not subject to
  a level of precision (#23).
- Breaking change: we have reversed our sense of rotation, a positive angle
  now rotates a point counter-clockwise about the pivot point (#25).
- Bug fix: a bug in matrix-vector multiplication had been reversing the
  direction of rotation and is now fixed (#25).

1.3.0 (2016-04-08)
------------------
- is_degenerate predicate is precise, not approximate (#22).

1.2.0 (2015-06-01)
------------------
- Enable pickling of Affine objects (#14).
- Sort out the mixed up shearing parameters (#12).

1.1.0 (2014-11-13)
------------------
- Add loadsw/dumpsw world file utilities (#6).
- Travis-CI and Coveralls config and web hooks added (#10).

1.0.1 (2014-10-20)
------------------
- set_epsilon() now actually sets module EPSILON (#4).
- add AUTHORS.txt.

1.0 (2014-05-27)
----------------
- Code ported from Casey Duncan's Planar package.
- from_gdal() class method added.
