Repository: joke2k/faker

Issue:
`pydecimal(left_digits=14)` produced value with 13 left digits
* Faker version: 22.6.0
* OS: macOS, Linux

I've encountered a situation where `pydecimal` appears to not respect `left_digits`:

```python
from faker import Faker

fake = Faker()
Faker.seed(0)

fake.pydecimal(left_digits=14, right_digits=2)  # Decimal("5550397399547.96")
```

"5550397399547.96" has 13 left digits. How is this possible?

Note I found this while running a suite of a couple of thousands of tests. One of the tests failed because the value produced did not have the expectated number of digits. If I run the failing test in isolation, it passes i.e. that specific value doesn't get generated. I'm only getting this when I run the whole suite.


Discussion:
I have found another case where

```python
fake.pydecimal(left_digits=8, right_digits=3)
```

produced the value:

```python
Decimal("-3337220.745")
```

Note I believe it has nothing to do with the sign because in the same test `fake.pydecimal(left_digits=7, right_digits=5)` produced `Decimal("-3467432.78381")`.

What can I do to debug this?
You should probably try to find a seed which generates a broken value each time. With this, debugging `pydecimal` itself should be possible.
Thanks for the suggestion. I found 15:

```python
from faker import Faker
fake = Faker()
fake.seed_instance(15)
fake.pydecimal(left_digits=8, right_digits=3)  # Decimal('8023002.531')
```
Upon further inspection, I found it's because it generates "08023002" for `left_number`. I'll see about a fix.

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
@@ -262,6 +262,21 @@ def _safe_random_int(self, min_value: float, max_value: float, positive: bool) -
     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)
 
+    def _random_int_of_length(self, length: int) -> int:
+        """Generate a random integer of a given length
+
+        If length is 0, so is the number. Otherwise the first digit must not be 0.
+        """
+
+        if length < 0:
+            raise ValueError("Length must be a non-negative integer.")
+        elif length == 0:
+            return 0
+        else:
+            min_value = 10 ** (length - 1)
+            max_value = (10**length) - 1
+            return self.pyint(min_value=min_value, max_value=max_value)
+
     def pydecimal(
         self,
         left_digits: Optional[int] = None,
@@ -310,7 +325,7 @@ def pydecimal(
                 min_left_digits = math.ceil(math.log10(max(min_value or 1, 1)))
                 if left_digits is None:
                     left_digits = 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"
+                left_number = str(self._random_int_of_length(left_digits))
         else:
             if min_value is not None:
                 left_number = str(self.random_int(int(max(max_value or 0, 0)), int(abs(min_value))))
@@ -318,7 +333,7 @@ def pydecimal(
                 min_left_digits = math.ceil(math.log10(abs(min(max_value or 1, 1))))
                 if left_digits is None:
                     left_digits = 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"
+                left_number = str(self._random_int_of_length(left_digits))
 
         if right_digits is None:
             right_digits = self.random_int(0, max_random_digits)


Test patch: