We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
pyfloat provider with positive=True sometimes returns zero
* Faker version: 5.8.0
* OS: macOS 11.1

Call pyfloat with positive=True, and it will sometimes return a zero. 

### Steps to reproduce

Here's an example:

```
import faker
f=faker.Faker()
are_zero = [f.pyfloat(positive=True, max_value=10)==0 for _ in range(100)]
print(any(are_zero))
```

### Expected behavior

It should always print `False` always. 

### Actual behavior

Sometimes it's `True` with f.pyfloat() returning zero. 


--- 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 import string
2 import sys
3 import warnings
4 
5 from decimal import Decimal
6 
7 from .. import BaseProvider
8 
9 
10 class Provider(BaseProvider):
11     default_value_types = (
12         'str', 'str', 'str', 'str', 'float', 'int', 'int', 'decimal',
13         'date_time', 'uri', 'email',
14     )
15 
16     def _check_signature(self, value_types, allowed_types):
17         if value_types is not None and not isinstance(value_types, (list, tuple)):
18             value_types = [value_types]
19             warnings.warn(
20                 'Passing value types as positional arguments is going to be '
21                 'deprecated.  Pass them as a list or tuple instead.',
22                 PendingDeprecationWarning,
23             )
24         if value_types is None:
25             value_types = ()
26         return tuple(value_types) + allowed_types
27 
28     def pybool(self):
29         return self.random_int(0, 1) == 1
30 
31     def pystr(self, min_chars=None, max_chars=20):
32         """
33         Generates a random string of upper and lowercase letters.
34         :type min_chars: int
35         :type max_chars: int
36         :return: String. Random of random length between min and max characters.
37         """
38         if min_chars is None:
39             return "".join(self.random_letters(length=max_chars))
40         else:
41             assert (
42                 max_chars >= min_chars), "Maximum length must be greater than or equal to minium length"
43             return "".join(
44                 self.random_letters(
45                     length=self.generator.random.randint(min_chars, max_chars),
46                 ),
47             )
48 
49     def pystr_format(self, string_format='?#-###{{random_int}}{{random_letter}}', letters=string.ascii_letters):
50         return self.bothify(self.generator.parse(string_format), letters=letters)
51 
52     def pyfloat(self, left_digits=None, right_digits=None, positive=False,
53                 min_value=None, max_value=None):
54         if left_digits is not None and left_digits < 0:
55             raise ValueError(
56                 'A float number cannot have less than 0 digits in its '
57                 'integer part')
58         if right_digits is not None and right_digits < 0:
59             raise ValueError(
60                 'A float number cannot have less than 0 digits in its '
61                 'fractional part')
62         if left_digits == 0 and right_digits == 0:
63             raise ValueError(
64                 'A float number cannot have less than 0 digits in total')
65         if None not in (min_value, max_value) and min_value > max_value:
66             raise ValueError('Min value cannot be greater than max value')
67         if None not in (min_value, max_value) and min_value == max_value:
68             raise ValueError('Min and max value cannot be the same')
69         if positive and min_value is not None and min_value < 0:
70             raise ValueError(
71                 'Cannot combine positive=True and negative min_value')
72 
73         left_digits = left_digits if left_digits is not None else (
74             self.random_int(1, sys.float_info.dig))
75         right_digits = right_digits if right_digits is not None else (
76             self.random_int(0, sys.float_info.dig - left_digits))
77         sign = ''
78         if (min_value is not None) or (max_value is not None):
79             if max_value is not None and max_value < 0:
80                 max_value += 1  # as the random_int will be generated up to max_value - 1
81             if min_value is not None and min_value < 0:
82                 min_value += 1  # as we then append digits after the left_number
83             left_number = self._safe_random_int(
84                 min_value, max_value, positive,
85             )
86         else:
87             sign = '+' if positive else self.random_element(('+', '-'))
88             left_number = self.random_number(left_digits)
89 
90         return float(f'{sign}{left_number}.{self.random_number(right_digits)}')
91 
92     def _safe_random_int(self, min_value, max_value, positive):
93         orig_min_value = min_value
94         orig_max_value = max_value
95 
96         if min_value is None:
97             min_value = max_value - self.random_int()
98         if max_value is None:
99             max_value = min_value + self.random_int()
100         if positive:
101             min_value = max(min_value, 0)
102 
103         if min_value == max_value:
104             return self._safe_random_int(orig_min_value, orig_max_value, positive)
105         else:
106             return self.random_int(min_value, max_value - 1)
107 
108     def pyint(self, min_value=0, max_value=9999, step=1):
109         return self.generator.random_int(min_value, max_value, step=step)
110 
111     def pydecimal(self, left_digits=None, right_digits=None, positive=False,
112                   min_value=None, max_value=None):
113 
114         float_ = self.pyfloat(
115             left_digits, right_digits, positive, min_value, max_value)
116         return Decimal(str(float_))
117 
118     def pytuple(self, nb_elements=10, variable_nb_elements=True, value_types=None, *allowed_types):
119         return tuple(
120             self.pyset(
121                 nb_elements,
122                 variable_nb_elements,
123                 value_types,
124                 *allowed_types))
125 
126     def pyset(self, nb_elements=10, variable_nb_elements=True, value_types=None, *allowed_types):
127         return set(
128             self._pyiterable(
129                 nb_elements,
130                 variable_nb_elements,
131                 value_types,
132                 *allowed_types))
133 
134     def pylist(self, nb_elements=10, variable_nb_elements=True, value_types=None, *allowed_types):
135         return list(
136             self._pyiterable(
137                 nb_elements,
138                 variable_nb_elements,
139                 value_types,
140                 *allowed_types))
141 
142     def pyiterable(
143             self,
144             nb_elements=10,
145             variable_nb_elements=True,
146             value_types=None,
147             *allowed_types):
148         value_types = self._check_signature(value_types, allowed_types)
149         return self.random_element([self.pylist, self.pytuple, self.pyset])(
150             nb_elements, variable_nb_elements, value_types, *allowed_types)
151 
152     def _random_type(self, type_list):
153         value_type = self.random_element(type_list)
154 
155         method_name = f'py{value_type}'
156         if hasattr(self, method_name):
157             value_type = method_name
158 
159         return self.generator.format(value_type)
160 
161     def _pyiterable(
162             self,
163             nb_elements=10,
164             variable_nb_elements=True,
165             value_types=None,
166             *allowed_types):
167 
168         value_types = self._check_signature(value_types, allowed_types)
169 
170         value_types = [t if isinstance(t, str) else getattr(t, '__name__', type(t).__name__).lower()
171                        for t in value_types
172                        # avoid recursion
173                        if t not in ['iterable', 'list', 'tuple', 'dict', 'set']]
174         if not value_types:
175             value_types = self.default_value_types
176 
177         if variable_nb_elements:
178             nb_elements = self.randomize_nb_elements(nb_elements, min=1)
179 
180         for _ in range(nb_elements):
181             yield self._random_type(value_types)
182 
183     def pydict(self, nb_elements=10, variable_nb_elements=True, value_types=None, *allowed_types):
184         """
185         Returns a dictionary.
186 
187         :nb_elements: number of elements for dictionary
188         :variable_nb_elements: is use variable number of elements for dictionary
189         :value_types: type of dictionary values
190         """
191         if variable_nb_elements:
192             nb_elements = self.randomize_nb_elements(nb_elements, min=1)
193 
194         return dict(zip(
195             self.generator.words(nb_elements, unique=True),
196             self._pyiterable(nb_elements, False, value_types, *allowed_types),
197         ))
198 
199     def pystruct(self, count=10, value_types=None, *allowed_types):
200         value_types = self._check_signature(value_types, allowed_types)
201 
202         value_types = [t if isinstance(t, str) else getattr(t, '__name__', type(t).__name__).lower()
203                        for t in value_types
204                        # avoid recursion
205                        if t != 'struct']
206         if not value_types:
207             value_types = self.default_value_types
208 
209         types = []
210         d = {}
211         nd = {}
212         for i in range(count):
213             d[self.generator.word()] = self._random_type(value_types)
214             types.append(self._random_type(value_types))
215             nd[self.generator.word()] = {i: self._random_type(value_types),
216                                          i + 1: [self._random_type(value_types),
217                                                  self._random_type(value_types),
218                                                  self._random_type(value_types)],
219                                          i + 2: {i: self._random_type(value_types),
220                                                  i + 1: self._random_type(value_types),
221                                                  i + 2: [self._random_type(value_types),
222                                                          self._random_type(value_types)]}}
223         return types, d, nd
224
```
--- 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
@@ -66,9 +66,9 @@
             raise ValueError('Min value cannot be greater than max value')
         if None not in (min_value, max_value) and min_value == max_value:
             raise ValueError('Min and max value cannot be the same')
-        if positive and min_value is not None and min_value < 0:
+        if positive and min_value is not None and min_value <= 0:
             raise ValueError(
-                'Cannot combine positive=True and negative min_value')
+                'Cannot combine positive=True with negative or zero min_value')
 
         left_digits = left_digits if left_digits is not None else (
             self.random_int(1, sys.float_info.dig))
@@ -87,7 +87,10 @@
             sign = '+' if positive else self.random_element(('+', '-'))
             left_number = self.random_number(left_digits)
 
-        return float(f'{sign}{left_number}.{self.random_number(right_digits)}')
+        result = float(f'{sign}{left_number}.{self.random_number(right_digits)}')
+        if positive and result == 0:
+            result += sys.float_info.epsilon
+        return result
 
     def _safe_random_int(self, min_value, max_value, positive):
         orig_min_value = min_value

{"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@@ -66,9 +66,9 @@\n             raise ValueError('Min value cannot be greater than max value')\n         if None not in (min_value, max_value) and min_value == max_value:\n             raise ValueError('Min and max value cannot be the same')\n-        if positive and min_value is not None and min_value < 0:\n+        if positive and min_value is not None and min_value <= 0:\n             raise ValueError(\n-                'Cannot combine positive=True and negative min_value')\n+                'Cannot combine positive=True with negative or zero min_value')\n \n         left_digits = left_digits if left_digits is not None else (\n             self.random_int(1, sys.float_info.dig))\n@@ -87,7 +87,10 @@\n             sign = '+' if positive else self.random_element(('+', '-'))\n             left_number = self.random_number(left_digits)\n \n-        return float(f'{sign}{left_number}.{self.random_number(right_digits)}')\n+        result = float(f'{sign}{left_number}.{self.random_number(right_digits)}')\n+        if positive and result == 0:\n+            result += sys.float_info.epsilon\n+        return result\n \n     def _safe_random_int(self, min_value, max_value, positive):\n         orig_min_value = min_value\n", "issue": "pyfloat provider with positive=True sometimes returns zero\n* Faker version: 5.8.0\r\n* OS: macOS 11.1\r\n\r\nCall pyfloat with positive=True, and it will sometimes return a zero. \r\n\r\n### Steps to reproduce\r\n\r\nHere's an example:\r\n\r\n```\r\nimport faker\r\nf=faker.Faker()\r\nare_zero = [f.pyfloat(positive=True, max_value=10)==0 for _ in range(100)]\r\nprint(any(are_zero))\r\n```\r\n\r\n### Expected behavior\r\n\r\nIt should always print `False` always. \r\n\r\n### Actual behavior\r\n\r\nSometimes it's `True` with f.pyfloat() returning zero. \r\n\n", "before_files": [{"content": "import string\nimport sys\nimport warnings\n\nfrom decimal import Decimal\n\nfrom .. import BaseProvider\n\n\nclass Provider(BaseProvider):\n    default_value_types = (\n        'str', 'str', 'str', 'str', 'float', 'int', 'int', 'decimal',\n        'date_time', 'uri', 'email',\n    )\n\n    def _check_signature(self, value_types, allowed_types):\n        if value_types is not None and not isinstance(value_types, (list, tuple)):\n            value_types = [value_types]\n            warnings.warn(\n                'Passing value types as positional arguments is going to be '\n                'deprecated.  Pass them as a list or tuple instead.',\n                PendingDeprecationWarning,\n            )\n        if value_types is None:\n            value_types = ()\n        return tuple(value_types) + allowed_types\n\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 pystr_format(self, string_format='?#-###{{random_int}}{{random_letter}}', letters=string.ascii_letters):\n        return self.bothify(self.generator.parse(string_format), letters=letters)\n\n    def pyfloat(self, left_digits=None, right_digits=None, positive=False,\n                min_value=None, max_value=None):\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        if None not in (min_value, max_value) and min_value == max_value:\n            raise ValueError('Min and max value cannot be the same')\n        if positive and min_value is not None and min_value < 0:\n            raise ValueError(\n                'Cannot combine positive=True and negative min_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 max_value is not None and max_value < 0:\n                max_value += 1  # as the random_int will be generated up to max_value - 1\n            if min_value is not None and min_value < 0:\n                min_value += 1  # as we then append digits after the left_number\n            left_number = self._safe_random_int(\n                min_value, max_value, positive,\n            )\n        else:\n            sign = '+' if positive else self.random_element(('+', '-'))\n            left_number = self.random_number(left_digits)\n\n        return float(f'{sign}{left_number}.{self.random_number(right_digits)}')\n\n    def _safe_random_int(self, min_value, max_value, positive):\n        orig_min_value = min_value\n        orig_max_value = max_value\n\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        if positive:\n            min_value = max(min_value, 0)\n\n        if min_value == max_value:\n            return self._safe_random_int(orig_min_value, orig_max_value, positive)\n        else:\n            return self.random_int(min_value, max_value - 1)\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=None, *allowed_types):\n        return tuple(\n            self.pyset(\n                nb_elements,\n                variable_nb_elements,\n                value_types,\n                *allowed_types))\n\n    def pyset(self, nb_elements=10, variable_nb_elements=True, value_types=None, *allowed_types):\n        return set(\n            self._pyiterable(\n                nb_elements,\n                variable_nb_elements,\n                value_types,\n                *allowed_types))\n\n    def pylist(self, nb_elements=10, variable_nb_elements=True, value_types=None, *allowed_types):\n        return list(\n            self._pyiterable(\n                nb_elements,\n                variable_nb_elements,\n                value_types,\n                *allowed_types))\n\n    def pyiterable(\n            self,\n            nb_elements=10,\n            variable_nb_elements=True,\n            value_types=None,\n            *allowed_types):\n        value_types = self._check_signature(value_types, allowed_types)\n        return self.random_element([self.pylist, self.pytuple, self.pyset])(\n            nb_elements, variable_nb_elements, value_types, *allowed_types)\n\n    def _random_type(self, type_list):\n        value_type = self.random_element(type_list)\n\n        method_name = f'py{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=None,\n            *allowed_types):\n\n        value_types = self._check_signature(value_types, allowed_types)\n\n        value_types = [t if isinstance(t, str) 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 = self.default_value_types\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=None, *allowed_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, unique=True),\n            self._pyiterable(nb_elements, False, value_types, *allowed_types),\n        ))\n\n    def pystruct(self, count=10, value_types=None, *allowed_types):\n        value_types = self._check_signature(value_types, allowed_types)\n\n        value_types = [t if isinstance(t, str) 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 = self.default_value_types\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": "import string\nimport sys\nimport warnings\n\nfrom decimal import Decimal\n\nfrom .. import BaseProvider\n\n\nclass Provider(BaseProvider):\n    default_value_types = (\n        'str', 'str', 'str', 'str', 'float', 'int', 'int', 'decimal',\n        'date_time', 'uri', 'email',\n    )\n\n    def _check_signature(self, value_types, allowed_types):\n        if value_types is not None and not isinstance(value_types, (list, tuple)):\n            value_types = [value_types]\n            warnings.warn(\n                'Passing value types as positional arguments is going to be '\n                'deprecated.  Pass them as a list or tuple instead.',\n                PendingDeprecationWarning,\n            )\n        if value_types is None:\n            value_types = ()\n        return tuple(value_types) + allowed_types\n\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 pystr_format(self, string_format='?#-###{{random_int}}{{random_letter}}', letters=string.ascii_letters):\n        return self.bothify(self.generator.parse(string_format), letters=letters)\n\n    def pyfloat(self, left_digits=None, right_digits=None, positive=False,\n                min_value=None, max_value=None):\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        if None not in (min_value, max_value) and min_value == max_value:\n            raise ValueError('Min and max value cannot be the same')\n        if positive and min_value is not None and min_value <= 0:\n            raise ValueError(\n                'Cannot combine positive=True with negative or zero min_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 max_value is not None and max_value < 0:\n                max_value += 1  # as the random_int will be generated up to max_value - 1\n            if min_value is not None and min_value < 0:\n                min_value += 1  # as we then append digits after the left_number\n            left_number = self._safe_random_int(\n                min_value, max_value, positive,\n            )\n        else:\n            sign = '+' if positive else self.random_element(('+', '-'))\n            left_number = self.random_number(left_digits)\n\n        result = float(f'{sign}{left_number}.{self.random_number(right_digits)}')\n        if positive and result == 0:\n            result += sys.float_info.epsilon\n        return result\n\n    def _safe_random_int(self, min_value, max_value, positive):\n        orig_min_value = min_value\n        orig_max_value = max_value\n\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        if positive:\n            min_value = max(min_value, 0)\n\n        if min_value == max_value:\n            return self._safe_random_int(orig_min_value, orig_max_value, positive)\n        else:\n            return self.random_int(min_value, max_value - 1)\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=None, *allowed_types):\n        return tuple(\n            self.pyset(\n                nb_elements,\n                variable_nb_elements,\n                value_types,\n                *allowed_types))\n\n    def pyset(self, nb_elements=10, variable_nb_elements=True, value_types=None, *allowed_types):\n        return set(\n            self._pyiterable(\n                nb_elements,\n                variable_nb_elements,\n                value_types,\n                *allowed_types))\n\n    def pylist(self, nb_elements=10, variable_nb_elements=True, value_types=None, *allowed_types):\n        return list(\n            self._pyiterable(\n                nb_elements,\n                variable_nb_elements,\n                value_types,\n                *allowed_types))\n\n    def pyiterable(\n            self,\n            nb_elements=10,\n            variable_nb_elements=True,\n            value_types=None,\n            *allowed_types):\n        value_types = self._check_signature(value_types, allowed_types)\n        return self.random_element([self.pylist, self.pytuple, self.pyset])(\n            nb_elements, variable_nb_elements, value_types, *allowed_types)\n\n    def _random_type(self, type_list):\n        value_type = self.random_element(type_list)\n\n        method_name = f'py{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=None,\n            *allowed_types):\n\n        value_types = self._check_signature(value_types, allowed_types)\n\n        value_types = [t if isinstance(t, str) 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 = self.default_value_types\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=None, *allowed_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, unique=True),\n            self._pyiterable(nb_elements, False, value_types, *allowed_types),\n        ))\n\n    def pystruct(self, count=10, value_types=None, *allowed_types):\n        value_types = self._check_signature(value_types, allowed_types)\n\n        value_types = [t if isinstance(t, str) 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 = self.default_value_types\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"}]}