rasterio / affine

Affine transformation matrices
BSD 3-Clause "New" or "Revised" License
156 stars 28 forks source link

`__mul__` doesn't always return NotImplemented on failure #71

Closed Kirill888 closed 2 years ago

Kirill888 commented 2 years ago

I'm trying to implement __rmul__ for a custom type that takes Affine object on the left A * g --> g.__rmul__(A), this works fine except when g is iterable containing exactly two elements. Since then A.__mul__(g) goes into code path listed below and fails with ValueError

https://github.com/rasterio/affine/blob/78c20a0cfbb5ece3dfadc1a5550465936a4fa731/affine/__init__.py#L512-L516

I think return statement on line 516 above should be moved inside the try block.

sgillies commented 2 years ago

@Kirill888 can you explain more about how you get a ValueError? I tried multiplying a few generator expressions by an Affine object.

>>> Affine.identity() * (i for i in range(2))
(0.0, 1.0)
>>> Affine.identity() * ("s" for i in range(2))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/seangillies/projects/affine/affine/__init__.py", line 516, in __mul__
    return (vx * sa + vy * sb + sc, vx * sd + vy * se + sf)
TypeError: can't multiply sequence by non-int of type 'float'
Kirill888 commented 2 years ago

@Kirill888 can you explain more about how you get a ValueError? I tried multiplying a few generator expressions by an Affine object.

Sorry, my bad, I do indeed get TypeError not ValueError:

~/.envs/odc/lib/python3.8/site-packages/affine/__init__.py in __mul__(self, other)
    504             except Exception:
    505                 return NotImplemented
--> 506             return (vx * sa + vy * sb + sc, vx * sd + vy * se + sf)
    507 
    508     def __rmul__(self, other):

TypeError: unsupported operand type(s) for *: 'Geometry' and 'float'

This still prevents python from trying g.__rmul__(A)

sgillies commented 2 years ago

Fixed in version 2.3.1, uploaded a few seconds ago.