Repository: sdispater/pendulum

Issue:
Error dividing duration by float
<!--
  Hi there! Thank you for discovering and submitting an issue.

  Before you submit this; let's make sure of a few things.
  Please make sure the following boxes are ticked if they are correct.
  If not, please try and fulfill these first.
-->

<!-- Checked checkbox should look like this: [x] -->
- [x] I am on the [latest](https://github.com/sdispater/pendulum/releases/latest) Pendulum version.
- [x] I have searched the [issues](https://github.com/sdispater/pendulum/issues) of this repo and believe that this is not a duplicate.

<!--
  Once those are done, if you're able to fill in the following list with your information,
  it'd be very helpful to whoever handles the issue.
-->

- **OS version and name**: Windows 10, version 20H2
- **Pendulum version**: 2.1.2

## Issue
<!-- Now feel free to write your issue, but please be descriptive! Thanks again 🙌 ❤️ -->

In pendulum:
```python
import pendulum

d = pendulum.duration(hours=4, minutes=5)
d / 1.1
```

It gives the following error:
```python
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python\lib\site-packages\pendulum\duration.py", line 396, in __truediv__
    months=_divide_and_round(self._months, other),
  File "C:\Python\lib\site-packages\pendulum\duration.py", line 66, in __new__
    raise ValueError("Float year and months are not supported")
ValueError: Float year and months are not supported
```

Using datetime.timedelta:
```python
from datetime import timedelta

t = timedelta(seconds=4*3600+5*60)
t / 1.1
# datetime.timedelta(seconds=13363, microseconds=636364)
```

It doesn't raise any error. Both objects represent the same amount of time:
```python
from datetime import timedelta

import pendulum

d = pendulum.duration(hours=4, minutes=5)
t = timedelta(seconds=4*3600+5*60)
assert d.as_timedelta() == t
```

Discussion:

Patch:
diff --git a/pendulum/duration.py b/pendulum/duration.py
index 45df13d..47a6a38 100644
--- a/pendulum/duration.py
+++ b/pendulum/duration.py
@@ -23,6 +23,10 @@ def _divide_and_round(a, b):
     # Based on the reference implementation for divmod_near
     # in Objects/longobject.c.
     q, r = divmod(a, b)
+
+    if isinstance(q, float):
+        q = int(q)
+
     # round up if either r / b > 0.5, or r / b == 0.5 and q is odd.
     # The expression r / b > 0.5 is equivalent to 2 * r > b if b is
     # positive, 2 * r < b if b negative.


Test patch:
diff --git a/tests/duration/test_arithmetic.py b/tests/duration/test_arithmetic.py
index fad38b6..0f3283a 100644
--- a/tests/duration/test_arithmetic.py
+++ b/tests/duration/test_arithmetic.py
@@ -38,12 +38,24 @@ def test_divide():
     assert isinstance(mul, pendulum.Duration)
     assert_duration(mul, 0, 0, 0, 1, 0, 0, 17, 761111)
 
+    it = pendulum.duration(days=2, seconds=35, microseconds=522222)
+    mul = it / 1.1
+
+    assert isinstance(mul, pendulum.Duration)
+    assert_duration(mul, 0, 0, 0, 1, 19, 38, 43, 202020)
+
     it = pendulum.duration(years=2, months=4, days=2, seconds=35, microseconds=522222)
     mul = it / 2
 
     assert isinstance(mul, pendulum.Duration)
     assert_duration(mul, 1, 2, 0, 1, 0, 0, 17, 761111)
 
+    it = pendulum.duration(years=2, months=4, days=2, seconds=35, microseconds=522222)
+    mul = it / 2.0
+
+    assert isinstance(mul, pendulum.Duration)
+    assert_duration(mul, 1, 2, 0, 1, 0, 0, 17, 761111)
+
 
 def test_floor_divide():
     it = pendulum.duration(days=2, seconds=34, microseconds=522222)