We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
pyfloat producing values above max_value
* Faker version: 2.0.1
* OS: Windows 10

Calling `pyfloat` with the `max_value` set can produce values above `max_value` leading to issues.

### Steps to reproduce

Run my example code below.

### Expected behavior

Given my following example, I would expect to _only_ see numbers in the range `1 <= x <= 2`.

```
for _ in range(25):
    print(faker.pyfloat(min_value=1, max_value=2))
```

### Actual behavior

However, my example will produce values in the range `1 <= x < 3`.  This behavior is very confusing and unexpected.  Output I got from running my above example:

```
1.200055
2.709
2.319785
2.773763416717
1.521
1.9
2.52454
2.91
1.87016
2.35457
1.92215
1.7
2.461453
1.922252943
1.416632
1.448
2.0
1.5
2.31
2.5114
2.18
1.8
2.12503540581
2.0
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `faker/providers/python/__init__.py`
Content:
```
1 # coding=utf-8
2 
3 from __future__ import unicode_literals
4 
5 from decimal import Decimal
6 import sys
7 
8 import six
9 
10 from .. import BaseProvider
11 
12 
13 class Provider(BaseProvider):
14     def pybool(self):
15         return self.random_int(0, 1) == 1
16 
17     def pystr(self, min_chars=None, max_chars=20):
18         """
19         Generates a random string of upper and lowercase letters.
20         :type min_chars: int
21         :type max_chars: int
22         :return: String. Random of random length between min and max characters.
23         """
24         if min_chars is None:
25             return "".join(self.random_letters(length=max_chars))
26         else:
27             assert (
28                 max_chars >= min_chars), "Maximum length must be greater than or equal to minium length"
29             return "".join(
30                 self.random_letters(
31                     length=self.generator.random.randint(min_chars, max_chars),
32                 ),
33             )
34 
35     def pyfloat(self, left_digits=None, right_digits=None, positive=False,
36                 min_value=None, max_value=None):
37 
38         if left_digits is not None and left_digits < 0:
39             raise ValueError(
40                 'A float number cannot have less than 0 digits in its '
41                 'integer part')
42         if right_digits is not None and right_digits < 0:
43             raise ValueError(
44                 'A float number cannot have less than 0 digits in its '
45                 'fractional part')
46         if left_digits == 0 and right_digits == 0:
47             raise ValueError(
48                 'A float number cannot have less than 0 digits in total')
49         if None not in (min_value, max_value) and min_value > max_value:
50             raise ValueError('Min value cannot be greater than max value')
51 
52         left_digits = left_digits if left_digits is not None else (
53             self.random_int(1, sys.float_info.dig))
54         right_digits = right_digits if right_digits is not None else (
55             self.random_int(0, sys.float_info.dig - left_digits))
56         sign = ''
57         if (min_value is not None) or (max_value is not None):
58             if min_value is None:
59                 min_value = max_value - self.random_int()
60             if max_value is None:
61                 max_value = min_value + self.random_int()
62 
63             left_number = self.random_int(min_value, max_value)
64         else:
65             sign = '+' if positive else self.random_element(('+', '-'))
66             left_number = self.random_number(left_digits)
67 
68         return float("{0}{1}.{2}".format(
69             sign,
70             left_number,
71             self.random_number(right_digits),
72         ))
73 
74     def pyint(self, min_value=0, max_value=9999, step=1):
75         return self.generator.random_int(min_value, max_value, step=step)
76 
77     def pydecimal(self, left_digits=None, right_digits=None, positive=False,
78                   min_value=None, max_value=None):
79 
80         float_ = self.pyfloat(
81             left_digits, right_digits, positive, min_value, max_value)
82         return Decimal(str(float_))
83 
84     def pytuple(self, nb_elements=10, variable_nb_elements=True, *value_types):
85         return tuple(
86             self.pyset(
87                 nb_elements,
88                 variable_nb_elements,
89                 *value_types))
90 
91     def pyset(self, nb_elements=10, variable_nb_elements=True, *value_types):
92         return set(
93             self._pyiterable(
94                 nb_elements,
95                 variable_nb_elements,
96                 *value_types))
97 
98     def pylist(self, nb_elements=10, variable_nb_elements=True, *value_types):
99         return list(
100             self._pyiterable(
101                 nb_elements,
102                 variable_nb_elements,
103                 *value_types))
104 
105     def pyiterable(
106             self,
107             nb_elements=10,
108             variable_nb_elements=True,
109             *value_types):
110         return self.random_element([self.pylist, self.pytuple, self.pyset])(
111             nb_elements, variable_nb_elements, *value_types)
112 
113     def _random_type(self, type_list):
114         value_type = self.random_element(type_list)
115 
116         method_name = "py{0}".format(value_type)
117         if hasattr(self, method_name):
118             value_type = method_name
119 
120         return self.generator.format(value_type)
121 
122     def _pyiterable(
123             self,
124             nb_elements=10,
125             variable_nb_elements=True,
126             *value_types):
127 
128         value_types = [t if isinstance(t, six.string_types) else getattr(t, '__name__', type(t).__name__).lower()
129                        for t in value_types
130                        # avoid recursion
131                        if t not in ['iterable', 'list', 'tuple', 'dict', 'set']]
132         if not value_types:
133             value_types = ['str', 'str', 'str', 'str', 'float',
134                            'int', 'int', 'decimal', 'date_time', 'uri', 'email']
135 
136         if variable_nb_elements:
137             nb_elements = self.randomize_nb_elements(nb_elements, min=1)
138 
139         for _ in range(nb_elements):
140             yield self._random_type(value_types)
141 
142     def pydict(self, nb_elements=10, variable_nb_elements=True, *value_types):
143         """
144         Returns a dictionary.
145 
146         :nb_elements: number of elements for dictionary
147         :variable_nb_elements: is use variable number of elements for dictionary
148         :value_types: type of dictionary values
149         """
150         if variable_nb_elements:
151             nb_elements = self.randomize_nb_elements(nb_elements, min=1)
152 
153         return dict(zip(
154             self.generator.words(nb_elements),
155             self._pyiterable(nb_elements, False, *value_types),
156         ))
157 
158     def pystruct(self, count=10, *value_types):
159 
160         value_types = [t if isinstance(t, six.string_types) else getattr(t, '__name__', type(t).__name__).lower()
161                        for t in value_types
162                        # avoid recursion
163                        if t != 'struct']
164         if not value_types:
165             value_types = ['str', 'str', 'str', 'str', 'float',
166                            'int', 'int', 'decimal', 'date_time', 'uri', 'email']
167 
168         types = []
169         d = {}
170         nd = {}
171         for i in range(count):
172             d[self.generator.word()] = self._random_type(value_types)
173             types.append(self._random_type(value_types))
174             nd[self.generator.word()] = {i: self._random_type(value_types),
175                                          i + 1: [self._random_type(value_types),
176                                                  self._random_type(value_types),
177                                                  self._random_type(value_types)],
178                                          i + 2: {i: self._random_type(value_types),
179                                                  i + 1: self._random_type(value_types),
180                                                  i + 2: [self._random_type(value_types),
181                                                          self._random_type(value_types)]}}
182         return types, d, nd
183
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

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
@@ -60,7 +60,7 @@
             if max_value is None:
                 max_value = min_value + self.random_int()
 
-            left_number = self.random_int(min_value, max_value)
+            left_number = self.random_int(min_value, max_value - 1)
         else:
             sign = '+' if positive else self.random_element(('+', '-'))
             left_number = self.random_number(left_digits)

{"golden_diff": "diff --git a/faker/providers/python/__init__.py b/faker/providers/python/__init__.py\n--- a/faker/providers/python/__init__.py\n+++ b/faker/providers/python/__init__.py\n@@ -60,7 +60,7 @@\n             if max_value is None:\n                 max_value = min_value + self.random_int()\n \n-            left_number = self.random_int(min_value, max_value)\n+            left_number = self.random_int(min_value, max_value - 1)\n         else:\n             sign = '+' if positive else self.random_element(('+', '-'))\n             left_number = self.random_number(left_digits)\n", "issue": "pyfloat producing values above max_value\n* Faker version: 2.0.1\r\n* OS: Windows 10\r\n\r\nCalling `pyfloat` with the `max_value` set can produce values above `max_value` leading to issues.\r\n\r\n### Steps to reproduce\r\n\r\nRun my example code below.\r\n\r\n### Expected behavior\r\n\r\nGiven my following example, I would expect to _only_ see numbers in the range `1 <= x <= 2`.\r\n\r\n```\r\nfor _ in range(25):\r\n    print(faker.pyfloat(min_value=1, max_value=2))\r\n```\r\n\r\n### Actual behavior\r\n\r\nHowever, my example will produce values in the range `1 <= x < 3`.  This behavior is very confusing and unexpected.  Output I got from running my above example:\r\n\r\n```\r\n1.200055\r\n2.709\r\n2.319785\r\n2.773763416717\r\n1.521\r\n1.9\r\n2.52454\r\n2.91\r\n1.87016\r\n2.35457\r\n1.92215\r\n1.7\r\n2.461453\r\n1.922252943\r\n1.416632\r\n1.448\r\n2.0\r\n1.5\r\n2.31\r\n2.5114\r\n2.18\r\n1.8\r\n2.12503540581\r\n2.0\r\n```\r\n\n", "before_files": [{"content": "# coding=utf-8\n\nfrom __future__ import unicode_literals\n\nfrom decimal import Decimal\nimport sys\n\nimport six\n\nfrom .. import BaseProvider\n\n\nclass Provider(BaseProvider):\n    def pybool(self):\n        return self.random_int(0, 1) == 1\n\n    def pystr(self, min_chars=None, max_chars=20):\n        \"\"\"\n        Generates a random string of upper and lowercase letters.\n        :type min_chars: int\n        :type max_chars: int\n        :return: String. Random of random length between min and max characters.\n        \"\"\"\n        if min_chars is None:\n            return \"\".join(self.random_letters(length=max_chars))\n        else:\n            assert (\n                max_chars >= min_chars), \"Maximum length must be greater than or equal to minium length\"\n            return \"\".join(\n                self.random_letters(\n                    length=self.generator.random.randint(min_chars, max_chars),\n                ),\n            )\n\n    def pyfloat(self, left_digits=None, right_digits=None, positive=False,\n                min_value=None, max_value=None):\n\n        if left_digits is not None and left_digits < 0:\n            raise ValueError(\n                'A float number cannot have less than 0 digits in its '\n                'integer part')\n        if right_digits is not None and right_digits < 0:\n            raise ValueError(\n                'A float number cannot have less than 0 digits in its '\n                'fractional part')\n        if left_digits == 0 and right_digits == 0:\n            raise ValueError(\n                'A float number cannot have less than 0 digits in total')\n        if None not in (min_value, max_value) and min_value > max_value:\n            raise ValueError('Min value cannot be greater than max value')\n\n        left_digits = left_digits if left_digits is not None else (\n            self.random_int(1, sys.float_info.dig))\n        right_digits = right_digits if right_digits is not None else (\n            self.random_int(0, sys.float_info.dig - left_digits))\n        sign = ''\n        if (min_value is not None) or (max_value is not None):\n            if min_value is None:\n                min_value = max_value - self.random_int()\n            if max_value is None:\n                max_value = min_value + self.random_int()\n\n            left_number = self.random_int(min_value, max_value)\n        else:\n            sign = '+' if positive else self.random_element(('+', '-'))\n            left_number = self.random_number(left_digits)\n\n        return float(\"{0}{1}.{2}\".format(\n            sign,\n            left_number,\n            self.random_number(right_digits),\n        ))\n\n    def pyint(self, min_value=0, max_value=9999, step=1):\n        return self.generator.random_int(min_value, max_value, step=step)\n\n    def pydecimal(self, left_digits=None, right_digits=None, positive=False,\n                  min_value=None, max_value=None):\n\n        float_ = self.pyfloat(\n            left_digits, right_digits, positive, min_value, max_value)\n        return Decimal(str(float_))\n\n    def pytuple(self, nb_elements=10, variable_nb_elements=True, *value_types):\n        return tuple(\n            self.pyset(\n                nb_elements,\n                variable_nb_elements,\n                *value_types))\n\n    def pyset(self, nb_elements=10, variable_nb_elements=True, *value_types):\n        return set(\n            self._pyiterable(\n                nb_elements,\n                variable_nb_elements,\n                *value_types))\n\n    def pylist(self, nb_elements=10, variable_nb_elements=True, *value_types):\n        return list(\n            self._pyiterable(\n                nb_elements,\n                variable_nb_elements,\n                *value_types))\n\n    def pyiterable(\n            self,\n            nb_elements=10,\n            variable_nb_elements=True,\n            *value_types):\n        return self.random_element([self.pylist, self.pytuple, self.pyset])(\n            nb_elements, variable_nb_elements, *value_types)\n\n    def _random_type(self, type_list):\n        value_type = self.random_element(type_list)\n\n        method_name = \"py{0}\".format(value_type)\n        if hasattr(self, method_name):\n            value_type = method_name\n\n        return self.generator.format(value_type)\n\n    def _pyiterable(\n            self,\n            nb_elements=10,\n            variable_nb_elements=True,\n            *value_types):\n\n        value_types = [t if isinstance(t, six.string_types) else getattr(t, '__name__', type(t).__name__).lower()\n                       for t in value_types\n                       # avoid recursion\n                       if t not in ['iterable', 'list', 'tuple', 'dict', 'set']]\n        if not value_types:\n            value_types = ['str', 'str', 'str', 'str', 'float',\n                           'int', 'int', 'decimal', 'date_time', 'uri', 'email']\n\n        if variable_nb_elements:\n            nb_elements = self.randomize_nb_elements(nb_elements, min=1)\n\n        for _ in range(nb_elements):\n            yield self._random_type(value_types)\n\n    def pydict(self, nb_elements=10, variable_nb_elements=True, *value_types):\n        \"\"\"\n        Returns a dictionary.\n\n        :nb_elements: number of elements for dictionary\n        :variable_nb_elements: is use variable number of elements for dictionary\n        :value_types: type of dictionary values\n        \"\"\"\n        if variable_nb_elements:\n            nb_elements = self.randomize_nb_elements(nb_elements, min=1)\n\n        return dict(zip(\n            self.generator.words(nb_elements),\n            self._pyiterable(nb_elements, False, *value_types),\n        ))\n\n    def pystruct(self, count=10, *value_types):\n\n        value_types = [t if isinstance(t, six.string_types) else getattr(t, '__name__', type(t).__name__).lower()\n                       for t in value_types\n                       # avoid recursion\n                       if t != 'struct']\n        if not value_types:\n            value_types = ['str', 'str', 'str', 'str', 'float',\n                           'int', 'int', 'decimal', 'date_time', 'uri', 'email']\n\n        types = []\n        d = {}\n        nd = {}\n        for i in range(count):\n            d[self.generator.word()] = self._random_type(value_types)\n            types.append(self._random_type(value_types))\n            nd[self.generator.word()] = {i: self._random_type(value_types),\n                                         i + 1: [self._random_type(value_types),\n                                                 self._random_type(value_types),\n                                                 self._random_type(value_types)],\n                                         i + 2: {i: self._random_type(value_types),\n                                                 i + 1: self._random_type(value_types),\n                                                 i + 2: [self._random_type(value_types),\n                                                         self._random_type(value_types)]}}\n        return types, d, nd\n", "path": "faker/providers/python/__init__.py"}], "after_files": [{"content": "# coding=utf-8\n\nfrom __future__ import unicode_literals\n\nfrom decimal import Decimal\nimport sys\n\nimport six\n\nfrom .. import BaseProvider\n\n\nclass Provider(BaseProvider):\n    def pybool(self):\n        return self.random_int(0, 1) == 1\n\n    def pystr(self, min_chars=None, max_chars=20):\n        \"\"\"\n        Generates a random string of upper and lowercase letters.\n        :type min_chars: int\n        :type max_chars: int\n        :return: String. Random of random length between min and max characters.\n        \"\"\"\n        if min_chars is None:\n            return \"\".join(self.random_letters(length=max_chars))\n        else:\n            assert (\n                max_chars >= min_chars), \"Maximum length must be greater than or equal to minium length\"\n            return \"\".join(\n                self.random_letters(\n                    length=self.generator.random.randint(min_chars, max_chars),\n                ),\n            )\n\n    def pyfloat(self, left_digits=None, right_digits=None, positive=False,\n                min_value=None, max_value=None):\n\n        if left_digits is not None and left_digits < 0:\n            raise ValueError(\n                'A float number cannot have less than 0 digits in its '\n                'integer part')\n        if right_digits is not None and right_digits < 0:\n            raise ValueError(\n                'A float number cannot have less than 0 digits in its '\n                'fractional part')\n        if left_digits == 0 and right_digits == 0:\n            raise ValueError(\n                'A float number cannot have less than 0 digits in total')\n        if None not in (min_value, max_value) and min_value > max_value:\n            raise ValueError('Min value cannot be greater than max value')\n\n        left_digits = left_digits if left_digits is not None else (\n            self.random_int(1, sys.float_info.dig))\n        right_digits = right_digits if right_digits is not None else (\n            self.random_int(0, sys.float_info.dig - left_digits))\n        sign = ''\n        if (min_value is not None) or (max_value is not None):\n            if min_value is None:\n                min_value = max_value - self.random_int()\n            if max_value is None:\n                max_value = min_value + self.random_int()\n\n            left_number = self.random_int(min_value, max_value - 1)\n        else:\n            sign = '+' if positive else self.random_element(('+', '-'))\n            left_number = self.random_number(left_digits)\n\n        return float(\"{0}{1}.{2}\".format(\n            sign,\n            left_number,\n            self.random_number(right_digits),\n        ))\n\n    def pyint(self, min_value=0, max_value=9999, step=1):\n        return self.generator.random_int(min_value, max_value, step=step)\n\n    def pydecimal(self, left_digits=None, right_digits=None, positive=False,\n                  min_value=None, max_value=None):\n\n        float_ = self.pyfloat(\n            left_digits, right_digits, positive, min_value, max_value)\n        return Decimal(str(float_))\n\n    def pytuple(self, nb_elements=10, variable_nb_elements=True, *value_types):\n        return tuple(\n            self.pyset(\n                nb_elements,\n                variable_nb_elements,\n                *value_types))\n\n    def pyset(self, nb_elements=10, variable_nb_elements=True, *value_types):\n        return set(\n            self._pyiterable(\n                nb_elements,\n                variable_nb_elements,\n                *value_types))\n\n    def pylist(self, nb_elements=10, variable_nb_elements=True, *value_types):\n        return list(\n            self._pyiterable(\n                nb_elements,\n                variable_nb_elements,\n                *value_types))\n\n    def pyiterable(\n            self,\n            nb_elements=10,\n            variable_nb_elements=True,\n            *value_types):\n        return self.random_element([self.pylist, self.pytuple, self.pyset])(\n            nb_elements, variable_nb_elements, *value_types)\n\n    def _random_type(self, type_list):\n        value_type = self.random_element(type_list)\n\n        method_name = \"py{0}\".format(value_type)\n        if hasattr(self, method_name):\n            value_type = method_name\n\n        return self.generator.format(value_type)\n\n    def _pyiterable(\n            self,\n            nb_elements=10,\n            variable_nb_elements=True,\n            *value_types):\n\n        value_types = [t if isinstance(t, six.string_types) else getattr(t, '__name__', type(t).__name__).lower()\n                       for t in value_types\n                       # avoid recursion\n                       if t not in ['iterable', 'list', 'tuple', 'dict', 'set']]\n        if not value_types:\n            value_types = ['str', 'str', 'str', 'str', 'float',\n                           'int', 'int', 'decimal', 'date_time', 'uri', 'email']\n\n        if variable_nb_elements:\n            nb_elements = self.randomize_nb_elements(nb_elements, min=1)\n\n        for _ in range(nb_elements):\n            yield self._random_type(value_types)\n\n    def pydict(self, nb_elements=10, variable_nb_elements=True, *value_types):\n        \"\"\"\n        Returns a dictionary.\n\n        :nb_elements: number of elements for dictionary\n        :variable_nb_elements: is use variable number of elements for dictionary\n        :value_types: type of dictionary values\n        \"\"\"\n        if variable_nb_elements:\n            nb_elements = self.randomize_nb_elements(nb_elements, min=1)\n\n        return dict(zip(\n            self.generator.words(nb_elements),\n            self._pyiterable(nb_elements, False, *value_types),\n        ))\n\n    def pystruct(self, count=10, *value_types):\n\n        value_types = [t if isinstance(t, six.string_types) else getattr(t, '__name__', type(t).__name__).lower()\n                       for t in value_types\n                       # avoid recursion\n                       if t != 'struct']\n        if not value_types:\n            value_types = ['str', 'str', 'str', 'str', 'float',\n                           'int', 'int', 'decimal', 'date_time', 'uri', 'email']\n\n        types = []\n        d = {}\n        nd = {}\n        for i in range(count):\n            d[self.generator.word()] = self._random_type(value_types)\n            types.append(self._random_type(value_types))\n            nd[self.generator.word()] = {i: self._random_type(value_types),\n                                         i + 1: [self._random_type(value_types),\n                                                 self._random_type(value_types),\n                                                 self._random_type(value_types)],\n                                         i + 2: {i: self._random_type(value_types),\n                                                 i + 1: self._random_type(value_types),\n                                                 i + 2: [self._random_type(value_types),\n                                                         self._random_type(value_types)]}}\n        return types, d, nd\n", "path": "faker/providers/python/__init__.py"}]}