Repository: joke2k/faker

Issue:
pydecimal is not working really well when use max_value with low number
* Faker version: 9.2.0
* OS: python:3.8.8-slim (Docker) 

Brief summary of the issue goes here.
pydecimal is not working really well when use max_value with low number and use positive option or min_value with a close value to max_value. When you use this combination you usually get the max_value all the time. Because you always have set `max_random_digits = 100` https://github.com/joke2k/faker/blob/2c857e1fb64d0797bf352995815dbca56de23b8f/faker/providers/python/__init__.py#L178

The same behavior if you use min_value option with negative number with a close max_value. It always get max number o min number

### Steps to reproduce

 `fake.pydecimal(positive=True,  max_value=200)`

or `fake.pydecimal(min_value=0,  max_value=200)`

### Expected behavior

You like have a random decimal between 0 and 200 

### Actual behavior

You always get Decimal('200') because this line of code https://github.com/joke2k/faker/blob/2c857e1fb64d0797bf352995815dbca56de23b8f/faker/providers/python/__init__.py#L205


To solve this you can use same function like pyfloat inside your code https://github.com/joke2k/faker/blob/2c857e1fb64d0797bf352995815dbca56de23b8f/faker/providers/python/__init__.py#L79-L81




Discussion:
Thank you @antonioIrizar ! Do you have time to submit a Pull Request?

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
@@ -176,20 +176,10 @@ def pydecimal(self, left_digits=None, right_digits=None, positive=False,
 
         # if either left or right digits are not specified we randomly choose a length
         max_random_digits = 100
-        minimum_left_digits = len(str(min_value)) if min_value is not None else 1
-        if left_digits is None and right_digits is None:
-            right_digits = self.random_int(1, max_random_digits)
-            left_digits = self.random_int(minimum_left_digits, max_random_digits)
-        if left_digits is not None and right_digits is None:
-            right_digits = self.random_int(1, max_random_digits)
-        if left_digits is None and right_digits is not None:
-            left_digits = self.random_int(minimum_left_digits, max_random_digits)
-
-        left_number = ''.join([str(self.random_digit()) for i in range(0, left_digits)]) or '0'
-        if right_digits is not None:
-            right_number = ''.join([str(self.random_digit()) for i in range(0, right_digits)])
-        else:
-            right_number = ''
+        # Because if min_value is bigger than 10**100
+        max_digits_from_value = max(math.ceil(math.log10(abs(min_value or 1))),
+                                    math.ceil(math.log10(abs(max_value or 1))))
+        max_left_random_digits = max(max_random_digits, max_digits_from_value + 10)
 
         if min_value is not None and min_value >= 0:
             sign = '+'
@@ -198,6 +188,26 @@ def pydecimal(self, left_digits=None, right_digits=None, positive=False,
         else:
             sign = '+' if positive else self.random_element(('+', '-'))
 
+        if sign == '+':
+            if max_value is not None:
+                left_number = str(self.random_int(max(min_value or 0, 0), max_value))
+            else:
+                min_left_digits = math.ceil(math.log10(max(min_value or 1, 1)))
+                left_digits = left_digits or self.random_int(min_left_digits, max_left_random_digits)
+                left_number = ''.join([str(self.random_digit()) for i in range(0, left_digits)]) or '0'
+        else:
+            if min_value is not None:
+                left_number = str(self.random_int(max(max_value or 0, 0), abs(min_value)))
+            else:
+                min_left_digits = math.ceil(math.log10(abs(min(max_value or 1, 1))))
+                left_digits = left_digits or self.random_int(min_left_digits, max_left_random_digits)
+                left_number = ''.join([str(self.random_digit()) for i in range(0, left_digits)]) or '0'
+
+        if right_digits is None:
+            right_digits = self.random_int(0, max_random_digits)
+
+        right_number = ''.join([str(self.random_digit()) for i in range(0, right_digits)])
+
         result = Decimal(f'{sign}{left_number}.{right_number}')
 
         # Because the random result might have the same number of decimals as max_value the random number


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
@@ -372,6 +372,11 @@ def test_min_value_minus_one_hundred_doesnt_return_positive(self):
         result = self.fake.pydecimal(left_digits=3, right_digits=2, min_value=-999, max_value=-100)
         self.assertLess(result, -100)
 
+    def test_min_value_10_pow_1000_return_greater_number(self):
+        Faker.seed('2')
+        result = self.fake.pydecimal(min_value=10**1000)
+        self.assertGreater(result, 10**1000)
+
 
 class TestPystrFormat(unittest.TestCase):