[Git][debian-gis-team/python-affine][upstream] New upstream version 2.3.1
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Fri Mar 25 05:49:53 GMT 2022
Bas Couwenberg pushed to branch upstream at Debian GIS Project / python-affine
Commits:
9b68976e by Bas Couwenberg at 2022-03-25T06:40:58+01:00
New upstream version 2.3.1
- - - - -
7 changed files:
- .travis.yml
- CHANGES.txt
- README.rst
- affine/__init__.py
- affine/tests/test_transform.py
- − requirements.txt
- setup.py
Changes:
=====================================
.travis.yml
=====================================
@@ -5,12 +5,14 @@ python:
- 2.7
- 3.6
- 3.7
+ - pypy3
install:
- - pip install -r requirements.txt
+ - pip install flake8 pydocstyle
- pip install .[test]
script:
- - python -m pytest --cov affine --cov-report term-missing
+ - flake8
- python -m pydocstyle affine
+ - python -m pytest --cov affine --cov-report term-missing
after_success:
- coveralls
deploy:
=====================================
CHANGES.txt
=====================================
@@ -1,6 +1,14 @@
CHANGES
=======
+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)
------------------
=====================================
README.rst
=====================================
@@ -18,7 +18,7 @@ Usage
The 3x3 augmented affine transformation matrix for transformations in two
dimensions is illustrated below.
-.. ::
+::
| x' | | a b c | | x |
| y' | = | d e f | | y |
@@ -71,7 +71,7 @@ Usage with GIS data packages
Georeferenced raster datasets use affine transformations to map from image
coordinates to world coordinates. The ``affine.Affine.from_gdal()`` class
method helps convert `GDAL GeoTransform
-<http://www.gdal.org/classGDALDataset.html#af9593cc241e7d140f5f3c4798a43a668>`__,
+<https://gdal.org/user/raster_data_model.html#affine-geotransform>`__,
sequences of 6 numbers in which the first and fourth are the x and y offsets
and the second and sixth are the x and y pixel sizes.
=====================================
affine/__init__.py
=====================================
@@ -41,7 +41,7 @@ import warnings
__all__ = ['Affine']
__author__ = "Sean Gillies"
-__version__ = "2.3.0"
+__version__ = "2.3.1"
EPSILON = 1e-5
@@ -311,6 +311,16 @@ class Affine(
"""
return (self.c, self.a, self.b, self.f, self.d, self.e)
+ def to_shapely(self):
+ """Return an affine transformation matrix compatible with shapely
+
+ Shapely's affinity module expects an affine transformation matrix
+ in (a,b,d,e,xoff,yoff) order.
+
+ :rtype: tuple
+ """
+ return (self.a, self.b, self.d, self.e, self.xoff, self.yoff)
+
@property
def xoff(self):
"""Alias for 'c'"""
@@ -374,7 +384,7 @@ class Affine(
assuming it is in the form M = R S, where R is a rotation and S is a
scaling.
- Raises NotImplementedError for improper transformations.
+ Raises UndefinedRotationError for improper and degenerate transformations.
"""
a, b, _, c, d, _, _, _, _ = self
if self.is_proper or self.is_degenerate:
@@ -501,9 +511,9 @@ class Affine(
else:
try:
vx, vy = other
- except Exception:
+ return (vx * sa + vy * sb + sc, vx * sd + vy * se + sf)
+ except (ValueError, TypeError):
return NotImplemented
- return (vx * sa + vy * sb + sc, vx * sd + vy * se + sf)
def __rmul__(self, other):
"""Right hand multiplication
@@ -518,7 +528,8 @@ class Affine(
just a guarantee, since we would potentially return the wrong
answer in that case.
"""
- warnings.warn("Right multiplication will be prohibited in version 3.0", DeprecationWarning, stacklevel=2)
+ warnings.warn("Right multiplication will be prohibited in version 3.0",
+ DeprecationWarning, stacklevel=2)
assert not isinstance(other, Affine)
return self.__mul__(other)
=====================================
affine/tests/test_transform.py
=====================================
@@ -30,10 +30,9 @@
from __future__ import division
-import os
import math
import unittest
-import textwrap
+from textwrap import dedent
import pytest
@@ -101,14 +100,17 @@ class PyAffineTestCase(unittest.TestCase):
t['foobar']
def test_str(self):
- assert \
- str(Affine(1.111, 2.222, 3.333, -4.444, -5.555, 6.666)) \
- == "| 1.11, 2.22, 3.33|\n|-4.44,-5.55, 6.67|\n| 0.00, 0.00, 1.00|"
+ t = Affine(1.111, 2.222, 3.333, -4.444, -5.555, 6.666)
+ assert str(t) == dedent("""\
+ | 1.11, 2.22, 3.33|
+ |-4.44,-5.55, 6.67|
+ | 0.00, 0.00, 1.00|""")
def test_repr(self):
- assert \
- repr(Affine(1.111, 2.222, 3.456, 4.444, 5.5, 6.25)) == \
- os.linesep.join(["Affine(1.111, 2.222, 3.456,", " 4.444, 5.5, 6.25)"])
+ t = Affine(1.111, 2.222, 3.456, 4.444, 5.5, 6.25)
+ assert repr(t) == dedent("""\
+ Affine(1.111, 2.222, 3.456,
+ 4.444, 5.5, 6.25)""")
def test_identity_constructor(self):
ident = Affine.identity()
@@ -128,8 +130,8 @@ class PyAffineTestCase(unittest.TestCase):
(0, 1, 0,
1, 0, 0,
0, 0, 1)
- assert (perm*perm).is_identity
-
+ assert (perm*perm).is_identity
+
def test_translation_constructor(self):
trans = Affine.translation(2, -5)
assert isinstance(trans, Affine)
@@ -247,7 +249,8 @@ class PyAffineTestCase(unittest.TestCase):
0, 0, 1)
def test_rotation_constructor_with_pivot(self):
- assert tuple(Affine.rotation(60)) == tuple(Affine.rotation(60, pivot=(0, 0)))
+ assert tuple(Affine.rotation(60)) == \
+ tuple(Affine.rotation(60, pivot=(0, 0)))
rot = Affine.rotation(27, pivot=(2, -4))
r = math.radians(27)
s, c = math.sin(r), math.cos(r)
@@ -452,7 +455,7 @@ class PyAffineTestCase(unittest.TestCase):
assert affine.dumpsw(a) == s
def test_real_world(self):
- s = textwrap.dedent('''\
+ s = dedent('''\
39.9317755024
30.0907511581
30.0907511576
@@ -481,10 +484,15 @@ def test_gdal():
assert t.f == t.yoff == 237536.4
assert t.d == 0.0
assert t.e == -425.0
- assert tuple(t) == (425.0, 0.0, -237481.5, 0.0, -425.0, 237536.4, 0, 0, 1.0)
+ assert tuple(t) == (425.0, 0.0, -237481.5, 0.0, -425.0, 237536.4, 0, 0, 1)
assert t.to_gdal() == (-237481.5, 425.0, 0.0, 237536.4, 0.0, -425.0)
+def test_shapely():
+ t = Affine(425.0, 0.0, -237481.5, 0.0, -425.0, 237536.4)
+ assert t.to_shapely() == (425.0, 0.0, 0.0, -425, -237481.5, 237536.4)
+
+
def test_imul_number():
t = Affine(1, 2, 3, 4, 5, 6)
try:
@@ -534,7 +542,7 @@ def test_roundtrip():
def test_eccentricity():
assert Affine.identity().eccentricity == 0.0
assert Affine.scale(2).eccentricity == 0.0
- #assert_equal(Affine.scale(0).eccentricity, ?)
+ # assert_equal(Affine.scale(0).eccentricity, ?)
assert Affine.scale(2, 1).eccentricity == pytest.approx(math.sqrt(3) / 2)
assert Affine.scale(2, 3).eccentricity == pytest.approx(math.sqrt(5) / 3)
assert Affine.scale(1, 0).eccentricity == 1.0
@@ -551,7 +559,9 @@ def test_eccentricity_complex():
(Affine.rotation(77) * Affine.scale(2, 3)).eccentricity == \
pytest.approx(math.sqrt(5) / 3)
assert \
- (Affine.translation(32, -47) * Affine.rotation(77) * Affine.scale(2, 3)).eccentricity == \
+ (Affine.translation(32, -47) *
+ Affine.rotation(77) *
+ Affine.scale(2, 3)).eccentricity == \
pytest.approx(math.sqrt(5) / 3)
@@ -569,5 +579,32 @@ def test_rotation_improper():
Affine.scale(-1, 1).rotation_angle
+# See gh-71 for bug report motivating this test.
+def test_mul_fallback_unpack():
+ """Support fallback in case that other is a single object."""
+
+ class TextPoint:
+ """Not iterable, will trigger ValueError in Affine.__mul__."""
+ def __rmul__(self, other):
+ return other * (1, 2)
+
+ assert Affine.identity() * TextPoint() == (1, 2)
+
+
+# See gh-71 for bug report motivating this test.
+def test_mul_fallback_type_error():
+ """Support fallback in case that other is an unexpected type."""
+
+ class TextPoint:
+ """Iterable, but values trigger TypeError in Affine.__mul__."""
+ def __iter__(self):
+ return ("1", "2")
+
+ def __rmul__(self, other):
+ return other * (1, 2)
+
+ assert Affine.identity() * TextPoint() == (1, 2)
+
+
if __name__ == '__main__':
unittest.main()
=====================================
requirements.txt deleted
=====================================
@@ -1 +0,0 @@
-pydocstyle==2.1.1
=====================================
setup.py
=====================================
@@ -30,5 +30,6 @@ setup(
packages=find_packages(exclude=["ez_setup", "examples", "tests"]),
include_package_data=True,
zip_safe=True,
- extras_require={"test": ["pytest>=3.0", "pytest-cov", "pydocstyle", "coveralls"]},
+ extras_require={"test": ["pytest>=4.6", "pytest-cov", "pydocstyle",
+ "flake8", "coveralls"]},
)
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-affine/-/commit/9b68976efb858818b14fbad5901d61e4e818b893
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-affine/-/commit/9b68976efb858818b14fbad5901d61e4e818b893
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20220325/c3fb4811/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list