Repository: joke2k/faker

Issue:
ValueError: empty range for pyfloat
* Faker version: 14.0.0
* OS: macOS 12.5 (Monterey)

pyfloat throws ValueError when min_value and max_value have the same left digits. 

### Steps to reproduce

```
from faker import Faker

fake = Faker()

fake.pyfloat(min_value=1.25, max_value=1.75)
```

### Expected behavior

pyfloat returns a float between min_value and max_value

### Actual behavior

pyfloat throws exception

```
ValueError: empty range for randrange() (1, 1, 0)
```



Discussion:
Do you mind if I look into this?
As there is no fix for this available at the moment and this appears to be a valid bug, there should be nothing which holds you back here ;)

Resolving patch:
diff --git a/faker/providers/python/__init__.py b/faker/providers/python/__init__.py
--- a/faker/providers/python/__init__.py
+++ b/faker/providers/python/__init__.py
@@ -58,7 +58,13 @@ def _check_signature(self, value_types: Optional[TypesSpec], allowed_types: Opti
     def pybool(self) -> bool:
         return self.random_int(0, 1) == 1
 
-    def pystr(self, min_chars: Optional[int] = None, max_chars: int = 20, prefix: str = "", suffix: str = "") -> str:
+    def pystr(
+        self,
+        min_chars: Optional[int] = None,
+        max_chars: int = 20,
+        prefix: str = "",
+        suffix: str = "",
+    ) -> str:
         """
         Generates a random string of upper and lowercase letters.
         :return: Random of random length between min and max characters.
@@ -162,6 +168,11 @@ def pyfloat(
             result = min(result, 10**left_digits - 1)
             result = max(result, -(10**left_digits + 1))
 
+        # It's possible for the result to end up > than max_value
+        # This is a quick hack to ensure result is always smaller.
+        if max_value is not None:
+            if result > max_value:
+                result = result - (result - max_value)
         return result
 
     def _safe_random_int(self, min_value: float, max_value: float, positive: bool) -> int:
@@ -178,7 +189,11 @@ def _safe_random_int(self, min_value: float, max_value: float, positive: bool) -
         if min_value == max_value:
             return self._safe_random_int(orig_min_value, orig_max_value, positive)
         else:
-            return self.random_int(int(min_value), int(max_value - 1))
+            min_value = int(min_value)
+            max_value = int(max_value - 1)
+            if max_value < min_value:
+                max_value += 1
+            return self.random_int(min_value, max_value)
 
     def pyint(self, min_value: int = 0, max_value: int = 9999, step: int = 1) -> int:
         return self.generator.random_int(min_value, max_value, step=step)
@@ -385,7 +400,10 @@ def pydict(
         )
 
     def pystruct(
-        self, count: int = 10, value_types: Optional[TypesSpec] = None, allowed_types: Optional[TypesSpec] = None
+        self,
+        count: int = 10,
+        value_types: Optional[TypesSpec] = None,
+        allowed_types: Optional[TypesSpec] = None,
     ) -> Tuple[List, Dict, Dict]:
         value_types: TypesSpec = self._check_signature(value_types, allowed_types)
 


Test patch:
diff --git a/tests/providers/test_python.py b/tests/providers/test_python.py
--- a/tests/providers/test_python.py
+++ b/tests/providers/test_python.py
@@ -228,6 +228,9 @@ def test_float_min_and_max_value_does_not_warn(self):
         """
         self.fake.pyfloat(min_value=-1.0, max_value=1.0)
 
+    def test_float_min_and_max_value_with_same_whole(self):
+        self.fake.pyfloat(min_value=2.3, max_value=2.5)
+
 
 class TestPydecimal(unittest.TestCase):
     def setUp(self):