Repository: joke2k/faker
Pull request #1062 (2019-11-22 16:00:23)

Fix pyfloat out of min/max range
Ensure that pyfloat stays within range defined by min max

### What does this changes

Add tests, and shift min and max when they are negative

### What was wrong

When min was lower than 0, former code generated values between [min-1; max], so did for max

### How this fixes it

 * When the min is lower than `0`, we increase it of one (`-6` -> `-5`) as digits are appended later
 * When the max is lower than `0`, we increase it of one (`-6` -> `-5`) as the number before the comma is generated up to `max - 1`


Patch:
diff --git a/faker/providers/address/en_US/__init__.py b/faker/providers/address/en_US/__init__.py
index 3e15a838..f294093c 100644
--- a/faker/providers/address/en_US/__init__.py
+++ b/faker/providers/address/en_US/__init__.py
@@ -290,7 +290,7 @@ class Provider(AddressProvider):
         'MA': (1001, 2791), 'MI': (48001, 49971), 'MN': (55001, 56763),
         'MS': (38601, 39776), 'MO': (63001, 65899), 'MT': (59001, 59937),
         'NE': (68001, 68118), 'NV': (88901, 89883), 'NH': (3031, 3897),
-        'NJ': (7001, 8989), 'NM': (87001, 88441), 'NY': (6390, 6390),
+        'NJ': (7001, 8989), 'NM': (87001, 88441), 'NY': (10001, 14905),
         'NC': (27006, 28909), 'ND': (58001, 58856), 'OH': (43001, 45999),
         'OK': (73001, 73199), 'OR': (97001, 97920), 'PA': (15001, 19640),
         'RI': (2801, 2940), 'SC': (29001, 29948), 'SD': (57001, 57799),
diff --git a/faker/providers/python/__init__.py b/faker/providers/python/__init__.py
index 7440314e..c575ac05 100644
--- a/faker/providers/python/__init__.py
+++ b/faker/providers/python/__init__.py
@@ -60,6 +60,10 @@ class Provider(BaseProvider):
             self.random_int(0, sys.float_info.dig - left_digits))
         sign = ''
         if (min_value is not None) or (max_value is not None):
+            if max_value is not None and max_value < 0:
+                max_value += 1  # as the random_int will be generated up to max_value - 1
+            if min_value is not None and min_value < 0:
+                min_value += 1  # as we then append digits after the left_number
             left_number = self._safe_random_int(min_value, max_value)
         else:
             sign = '+' if positive else self.random_element(('+', '-'))


Test patch:
diff --git a/tests/test_factory.py b/tests/test_factory.py
index 677868ef..7a002153 100644
--- a/tests/test_factory.py
+++ b/tests/test_factory.py
@@ -474,11 +474,21 @@ class FactoryTestCase(unittest.TestCase):
         # tests for https://github.com/joke2k/faker/issues/994
         factory = Faker()
 
-        factory.seed_instance(5)
-        result = factory.pyfloat(min_value=0, max_value=1)
-
-        assert result >= 0.0
-        assert result <= 1.0
+        for i in range(20):
+            for min_value, max_value in [
+                (0, 1),
+                (-1, 1),
+                (None, -5),
+                (-5, None),
+                (None, 5),
+                (5, None),
+            ]:
+                factory.seed_instance(i)
+                result = factory.pyfloat(min_value=min_value, max_value=max_value)
+                if min_value is not None:
+                    assert result >= min_value
+                if max_value is not None:
+                    assert result <= max_value
 
     def test_negative_pyfloat(self):
         # tests for https://github.com/joke2k/faker/issues/813