We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Ensure words() returns a unique list of words without duplicates
When calling `words(10)` there is no guarantee that the returned list of elements is unique.   While I could do `set(words(10))`, this may only return 9 items when I am in need of 10.

If creating a list of words with potential duplicates is a useful feature to some, maybe adding an optional parameter called `unique` to the `words` generator could prove useful.

--- 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/lorem/__init__.py`
Content:
```
1 localized = True
2 
3 # 'Latin' is the default locale
4 default_locale = 'la'
5 
6 
7 from .. import BaseProvider
8 
9 
10 class Provider(BaseProvider):
11     """Will provide methods to retrieve lorem content
12 
13     Attributes:
14         sentence_punctuation (str): End of sentence punctuation
15         word_connector (str): Default connector between words
16 
17     Methods:
18         word: Generate a random word
19         words: Generate a list containing random words
20         sentence: Generate a random sentence
21         sentences: Generate a list containing sentences
22         paragraph: Generate a single paragraph
23         paragraphs: Generate many paragraphs
24         text: Generate a text string.
25     """
26     word_connector = ' '
27     sentence_punctuation = '.'
28 
29     def words(self, nb=3, ext_word_list=None):
30         """
31         :returns: An array of random words. for example: ['Lorem', 'ipsum', 'dolor']
32 
33         Keyword arguments:
34         :param nb: how many words to return
35         :param ext_word_list: a list of words you would like to have instead of
36             'Lorem ipsum'
37 
38         :rtype: list
39         """
40         word_list = ext_word_list if ext_word_list else self.word_list
41         return self.random_choices(word_list, length=nb)
42 
43     def word(self, ext_word_list=None):
44         """
45         :returns: A random word, eg: 'lorem'
46 
47         :param ext_word_list: a list of words you would like to have instead of
48             'Lorem ipsum'
49 
50         :rtype: str
51         """
52         return self.words(1, ext_word_list)[0]
53 
54     def sentence(self, nb_words=6, variable_nb_words=True, ext_word_list=None):
55         """
56         Generate a random sentence
57         :example 'Lorem ipsum dolor sit amet.'
58 
59         :param nb_words: around how many words the sentence should contain
60         :param variable_nb_words: set to false if you want exactly ``nb``
61             words returned, otherwise the result may include a number of words
62             of ``nb`` +/-40% (with a minimum of 1)
63         :param ext_word_list: a list of words you would like to have instead of
64             'Lorem ipsum'.
65 
66         :rtype: str
67         """
68         if nb_words <= 0:
69             return ''
70 
71         if variable_nb_words:
72             nb_words = self.randomize_nb_elements(nb_words, min=1)
73 
74         words = self.words(nb=nb_words, ext_word_list=ext_word_list)
75         words[0] = words[0].title()
76 
77         return self.word_connector.join(words) + self.sentence_punctuation
78 
79     def sentences(self, nb=3, ext_word_list=None):
80         """
81         Generate an array of sentences
82         :example ['Lorem ipsum dolor sit amet.', 'Consectetur adipisicing eli.']
83 
84         Keyword arguments:
85         :param nb: how many sentences to return
86         :param ext_word_list: a list of words you would like to have instead of
87             'Lorem ipsum'.
88 
89         :rtype: list
90         """
91         return [self.sentence(ext_word_list=ext_word_list)
92                 for _ in range(0, nb)]
93 
94     def paragraph(
95             self,
96             nb_sentences=3,
97             variable_nb_sentences=True,
98             ext_word_list=None):
99         """
100         :returns: A single paragraph. For example: 'Sapiente sunt omnis. Ut
101             pariatur ad autem ducimus et. Voluptas rem voluptas sint modi dolorem amet.'
102 
103         Keyword arguments:
104         :param nb_sentences: around how many sentences the paragraph should contain
105         :param variable_nb_sentences: set to false if you want exactly ``nb``
106             sentences returned, otherwise the result may include a number of
107             sentences of ``nb`` +/-40% (with a minimum of 1)
108         :param ext_word_list: a list of words you would like to have instead of
109             'Lorem ipsum'.
110 
111         :rtype: str
112         """
113         if nb_sentences <= 0:
114             return ''
115 
116         if variable_nb_sentences:
117             nb_sentences = self.randomize_nb_elements(nb_sentences, min=1)
118 
119         para = self.word_connector.join(self.sentences(
120             nb_sentences, ext_word_list=ext_word_list
121         ))
122 
123         return para
124 
125     def paragraphs(self, nb=3, ext_word_list=None):
126         """
127         Generate an array of paragraphs
128         :example [paragraph1, paragraph2, paragraph3]
129         :param nb: how many paragraphs to return
130         :param ext_word_list: a list of words you would like to have instead of
131             'Lorem ipsum'.
132 
133         :rtype: list
134         """
135 
136         return [self.paragraph(ext_word_list=ext_word_list)
137                 for _ in range(0, nb)]
138 
139     def text(self, max_nb_chars=200, ext_word_list=None):
140         """
141         Generate a text string.
142         Depending on the ``max_nb_chars, returns a string made of words, sentences, or paragraphs.
143         :example 'Sapiente sunt omnis. Ut pariatur ad autem ducimus et. Voluptas rem voluptas sint modi dolorem amet.'
144 
145         Keyword arguments:
146         :param max_nb_chars: Maximum number of characters the text should contain (minimum 5)
147         :param ext_word_list: a list of words you would like to have instead of 'Lorem ipsum'.
148 
149         :rtype str
150         """
151         text = []
152         if max_nb_chars < 5:
153             raise ValueError(
154                 'text() can only generate text of at least 5 characters')
155 
156         if max_nb_chars < 25:
157             # join words
158             while not text:
159                 size = 0
160                 # determine how many words are needed to reach the $max_nb_chars
161                 # once;
162                 while size < max_nb_chars:
163                     word = (self.word_connector if size else '') + \
164                         self.word(ext_word_list=ext_word_list)
165                     text.append(word)
166                     size += len(word)
167                 text.pop()
168             text[0] = text[0][0].upper() + text[0][1:]
169             last_index = len(text) - 1
170             text[last_index] += self.sentence_punctuation
171         elif max_nb_chars < 100:
172             # join sentences
173             while not text:
174                 size = 0
175                 # determine how many sentences are needed to reach the
176                 # $max_nb_chars once
177                 while size < max_nb_chars:
178                     sentence = (self.word_connector if size else '') + \
179                         self.sentence(ext_word_list=ext_word_list)
180                     text.append(sentence)
181                     size += len(sentence)
182                 text.pop()
183         else:
184             # join paragraphs
185             while not text:
186                 size = 0
187                 # determine how many paragraphs are needed to reach the
188                 # $max_nb_chars once
189                 while size < max_nb_chars:
190                     paragraph = ('\n' if size else '') + \
191                         self.paragraph(ext_word_list=ext_word_list)
192                     text.append(paragraph)
193                     size += len(paragraph)
194                 text.pop()
195 
196         return "".join(text)
197
```
--- 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/lorem/__init__.py b/faker/providers/lorem/__init__.py
--- a/faker/providers/lorem/__init__.py
+++ b/faker/providers/lorem/__init__.py
@@ -26,7 +26,7 @@
     word_connector = ' '
     sentence_punctuation = '.'
 
-    def words(self, nb=3, ext_word_list=None):
+    def words(self, nb=3, ext_word_list=None, unique=False):
         """
         :returns: An array of random words. for example: ['Lorem', 'ipsum', 'dolor']
 
@@ -34,10 +34,13 @@
         :param nb: how many words to return
         :param ext_word_list: a list of words you would like to have instead of
             'Lorem ipsum'
+        :param unique: If True, the returned word list will contain unique words
 
         :rtype: list
         """
         word_list = ext_word_list if ext_word_list else self.word_list
+        if unique:
+            return self.random_sample(word_list, length=nb)
         return self.random_choices(word_list, length=nb)
 
     def word(self, ext_word_list=None):

{"golden_diff": "diff --git a/faker/providers/lorem/__init__.py b/faker/providers/lorem/__init__.py\n--- a/faker/providers/lorem/__init__.py\n+++ b/faker/providers/lorem/__init__.py\n@@ -26,7 +26,7 @@\n     word_connector = ' '\n     sentence_punctuation = '.'\n \n-    def words(self, nb=3, ext_word_list=None):\n+    def words(self, nb=3, ext_word_list=None, unique=False):\n         \"\"\"\n         :returns: An array of random words. for example: ['Lorem', 'ipsum', 'dolor']\n \n@@ -34,10 +34,13 @@\n         :param nb: how many words to return\n         :param ext_word_list: a list of words you would like to have instead of\n             'Lorem ipsum'\n+        :param unique: If True, the returned word list will contain unique words\n \n         :rtype: list\n         \"\"\"\n         word_list = ext_word_list if ext_word_list else self.word_list\n+        if unique:\n+            return self.random_sample(word_list, length=nb)\n         return self.random_choices(word_list, length=nb)\n \n     def word(self, ext_word_list=None):\n", "issue": "Ensure words() returns a unique list of words without duplicates\nWhen calling `words(10)` there is no guarantee that the returned list of elements is unique.   While I could do `set(words(10))`, this may only return 9 items when I am in need of 10.\r\n\r\nIf creating a list of words with potential duplicates is a useful feature to some, maybe adding an optional parameter called `unique` to the `words` generator could prove useful.\n", "before_files": [{"content": "localized = True\n\n# 'Latin' is the default locale\ndefault_locale = 'la'\n\n\nfrom .. import BaseProvider\n\n\nclass Provider(BaseProvider):\n    \"\"\"Will provide methods to retrieve lorem content\n\n    Attributes:\n        sentence_punctuation (str): End of sentence punctuation\n        word_connector (str): Default connector between words\n\n    Methods:\n        word: Generate a random word\n        words: Generate a list containing random words\n        sentence: Generate a random sentence\n        sentences: Generate a list containing sentences\n        paragraph: Generate a single paragraph\n        paragraphs: Generate many paragraphs\n        text: Generate a text string.\n    \"\"\"\n    word_connector = ' '\n    sentence_punctuation = '.'\n\n    def words(self, nb=3, ext_word_list=None):\n        \"\"\"\n        :returns: An array of random words. for example: ['Lorem', 'ipsum', 'dolor']\n\n        Keyword arguments:\n        :param nb: how many words to return\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'\n\n        :rtype: list\n        \"\"\"\n        word_list = ext_word_list if ext_word_list else self.word_list\n        return self.random_choices(word_list, length=nb)\n\n    def word(self, ext_word_list=None):\n        \"\"\"\n        :returns: A random word, eg: 'lorem'\n\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'\n\n        :rtype: str\n        \"\"\"\n        return self.words(1, ext_word_list)[0]\n\n    def sentence(self, nb_words=6, variable_nb_words=True, ext_word_list=None):\n        \"\"\"\n        Generate a random sentence\n        :example 'Lorem ipsum dolor sit amet.'\n\n        :param nb_words: around how many words the sentence should contain\n        :param variable_nb_words: set to false if you want exactly ``nb``\n            words returned, otherwise the result may include a number of words\n            of ``nb`` +/-40% (with a minimum of 1)\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'.\n\n        :rtype: str\n        \"\"\"\n        if nb_words <= 0:\n            return ''\n\n        if variable_nb_words:\n            nb_words = self.randomize_nb_elements(nb_words, min=1)\n\n        words = self.words(nb=nb_words, ext_word_list=ext_word_list)\n        words[0] = words[0].title()\n\n        return self.word_connector.join(words) + self.sentence_punctuation\n\n    def sentences(self, nb=3, ext_word_list=None):\n        \"\"\"\n        Generate an array of sentences\n        :example ['Lorem ipsum dolor sit amet.', 'Consectetur adipisicing eli.']\n\n        Keyword arguments:\n        :param nb: how many sentences to return\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'.\n\n        :rtype: list\n        \"\"\"\n        return [self.sentence(ext_word_list=ext_word_list)\n                for _ in range(0, nb)]\n\n    def paragraph(\n            self,\n            nb_sentences=3,\n            variable_nb_sentences=True,\n            ext_word_list=None):\n        \"\"\"\n        :returns: A single paragraph. For example: 'Sapiente sunt omnis. Ut\n            pariatur ad autem ducimus et. Voluptas rem voluptas sint modi dolorem amet.'\n\n        Keyword arguments:\n        :param nb_sentences: around how many sentences the paragraph should contain\n        :param variable_nb_sentences: set to false if you want exactly ``nb``\n            sentences returned, otherwise the result may include a number of\n            sentences of ``nb`` +/-40% (with a minimum of 1)\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'.\n\n        :rtype: str\n        \"\"\"\n        if nb_sentences <= 0:\n            return ''\n\n        if variable_nb_sentences:\n            nb_sentences = self.randomize_nb_elements(nb_sentences, min=1)\n\n        para = self.word_connector.join(self.sentences(\n            nb_sentences, ext_word_list=ext_word_list\n        ))\n\n        return para\n\n    def paragraphs(self, nb=3, ext_word_list=None):\n        \"\"\"\n        Generate an array of paragraphs\n        :example [paragraph1, paragraph2, paragraph3]\n        :param nb: how many paragraphs to return\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'.\n\n        :rtype: list\n        \"\"\"\n\n        return [self.paragraph(ext_word_list=ext_word_list)\n                for _ in range(0, nb)]\n\n    def text(self, max_nb_chars=200, ext_word_list=None):\n        \"\"\"\n        Generate a text string.\n        Depending on the ``max_nb_chars, returns a string made of words, sentences, or paragraphs.\n        :example 'Sapiente sunt omnis. Ut pariatur ad autem ducimus et. Voluptas rem voluptas sint modi dolorem amet.'\n\n        Keyword arguments:\n        :param max_nb_chars: Maximum number of characters the text should contain (minimum 5)\n        :param ext_word_list: a list of words you would like to have instead of 'Lorem ipsum'.\n\n        :rtype str\n        \"\"\"\n        text = []\n        if max_nb_chars < 5:\n            raise ValueError(\n                'text() can only generate text of at least 5 characters')\n\n        if max_nb_chars < 25:\n            # join words\n            while not text:\n                size = 0\n                # determine how many words are needed to reach the $max_nb_chars\n                # once;\n                while size < max_nb_chars:\n                    word = (self.word_connector if size else '') + \\\n                        self.word(ext_word_list=ext_word_list)\n                    text.append(word)\n                    size += len(word)\n                text.pop()\n            text[0] = text[0][0].upper() + text[0][1:]\n            last_index = len(text) - 1\n            text[last_index] += self.sentence_punctuation\n        elif max_nb_chars < 100:\n            # join sentences\n            while not text:\n                size = 0\n                # determine how many sentences are needed to reach the\n                # $max_nb_chars once\n                while size < max_nb_chars:\n                    sentence = (self.word_connector if size else '') + \\\n                        self.sentence(ext_word_list=ext_word_list)\n                    text.append(sentence)\n                    size += len(sentence)\n                text.pop()\n        else:\n            # join paragraphs\n            while not text:\n                size = 0\n                # determine how many paragraphs are needed to reach the\n                # $max_nb_chars once\n                while size < max_nb_chars:\n                    paragraph = ('\\n' if size else '') + \\\n                        self.paragraph(ext_word_list=ext_word_list)\n                    text.append(paragraph)\n                    size += len(paragraph)\n                text.pop()\n\n        return \"\".join(text)\n", "path": "faker/providers/lorem/__init__.py"}], "after_files": [{"content": "localized = True\n\n# 'Latin' is the default locale\ndefault_locale = 'la'\n\n\nfrom .. import BaseProvider\n\n\nclass Provider(BaseProvider):\n    \"\"\"Will provide methods to retrieve lorem content\n\n    Attributes:\n        sentence_punctuation (str): End of sentence punctuation\n        word_connector (str): Default connector between words\n\n    Methods:\n        word: Generate a random word\n        words: Generate a list containing random words\n        sentence: Generate a random sentence\n        sentences: Generate a list containing sentences\n        paragraph: Generate a single paragraph\n        paragraphs: Generate many paragraphs\n        text: Generate a text string.\n    \"\"\"\n    word_connector = ' '\n    sentence_punctuation = '.'\n\n    def words(self, nb=3, ext_word_list=None, unique=False):\n        \"\"\"\n        :returns: An array of random words. for example: ['Lorem', 'ipsum', 'dolor']\n\n        Keyword arguments:\n        :param nb: how many words to return\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'\n        :param unique: If True, the returned word list will contain unique words\n\n        :rtype: list\n        \"\"\"\n        word_list = ext_word_list if ext_word_list else self.word_list\n        if unique:\n            return self.random_sample(word_list, length=nb)\n        return self.random_choices(word_list, length=nb)\n\n    def word(self, ext_word_list=None):\n        \"\"\"\n        :returns: A random word, eg: 'lorem'\n\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'\n\n        :rtype: str\n        \"\"\"\n        return self.words(1, ext_word_list)[0]\n\n    def sentence(self, nb_words=6, variable_nb_words=True, ext_word_list=None):\n        \"\"\"\n        Generate a random sentence\n        :example 'Lorem ipsum dolor sit amet.'\n\n        :param nb_words: around how many words the sentence should contain\n        :param variable_nb_words: set to false if you want exactly ``nb``\n            words returned, otherwise the result may include a number of words\n            of ``nb`` +/-40% (with a minimum of 1)\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'.\n\n        :rtype: str\n        \"\"\"\n        if nb_words <= 0:\n            return ''\n\n        if variable_nb_words:\n            nb_words = self.randomize_nb_elements(nb_words, min=1)\n\n        words = self.words(nb=nb_words, ext_word_list=ext_word_list)\n        words[0] = words[0].title()\n\n        return self.word_connector.join(words) + self.sentence_punctuation\n\n    def sentences(self, nb=3, ext_word_list=None):\n        \"\"\"\n        Generate an array of sentences\n        :example ['Lorem ipsum dolor sit amet.', 'Consectetur adipisicing eli.']\n\n        Keyword arguments:\n        :param nb: how many sentences to return\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'.\n\n        :rtype: list\n        \"\"\"\n        return [self.sentence(ext_word_list=ext_word_list)\n                for _ in range(0, nb)]\n\n    def paragraph(\n            self,\n            nb_sentences=3,\n            variable_nb_sentences=True,\n            ext_word_list=None):\n        \"\"\"\n        :returns: A single paragraph. For example: 'Sapiente sunt omnis. Ut\n            pariatur ad autem ducimus et. Voluptas rem voluptas sint modi dolorem amet.'\n\n        Keyword arguments:\n        :param nb_sentences: around how many sentences the paragraph should contain\n        :param variable_nb_sentences: set to false if you want exactly ``nb``\n            sentences returned, otherwise the result may include a number of\n            sentences of ``nb`` +/-40% (with a minimum of 1)\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'.\n\n        :rtype: str\n        \"\"\"\n        if nb_sentences <= 0:\n            return ''\n\n        if variable_nb_sentences:\n            nb_sentences = self.randomize_nb_elements(nb_sentences, min=1)\n\n        para = self.word_connector.join(self.sentences(\n            nb_sentences, ext_word_list=ext_word_list\n        ))\n\n        return para\n\n    def paragraphs(self, nb=3, ext_word_list=None):\n        \"\"\"\n        Generate an array of paragraphs\n        :example [paragraph1, paragraph2, paragraph3]\n        :param nb: how many paragraphs to return\n        :param ext_word_list: a list of words you would like to have instead of\n            'Lorem ipsum'.\n\n        :rtype: list\n        \"\"\"\n\n        return [self.paragraph(ext_word_list=ext_word_list)\n                for _ in range(0, nb)]\n\n    def text(self, max_nb_chars=200, ext_word_list=None):\n        \"\"\"\n        Generate a text string.\n        Depending on the ``max_nb_chars, returns a string made of words, sentences, or paragraphs.\n        :example 'Sapiente sunt omnis. Ut pariatur ad autem ducimus et. Voluptas rem voluptas sint modi dolorem amet.'\n\n        Keyword arguments:\n        :param max_nb_chars: Maximum number of characters the text should contain (minimum 5)\n        :param ext_word_list: a list of words you would like to have instead of 'Lorem ipsum'.\n\n        :rtype str\n        \"\"\"\n        text = []\n        if max_nb_chars < 5:\n            raise ValueError(\n                'text() can only generate text of at least 5 characters')\n\n        if max_nb_chars < 25:\n            # join words\n            while not text:\n                size = 0\n                # determine how many words are needed to reach the $max_nb_chars\n                # once;\n                while size < max_nb_chars:\n                    word = (self.word_connector if size else '') + \\\n                        self.word(ext_word_list=ext_word_list)\n                    text.append(word)\n                    size += len(word)\n                text.pop()\n            text[0] = text[0][0].upper() + text[0][1:]\n            last_index = len(text) - 1\n            text[last_index] += self.sentence_punctuation\n        elif max_nb_chars < 100:\n            # join sentences\n            while not text:\n                size = 0\n                # determine how many sentences are needed to reach the\n                # $max_nb_chars once\n                while size < max_nb_chars:\n                    sentence = (self.word_connector if size else '') + \\\n                        self.sentence(ext_word_list=ext_word_list)\n                    text.append(sentence)\n                    size += len(sentence)\n                text.pop()\n        else:\n            # join paragraphs\n            while not text:\n                size = 0\n                # determine how many paragraphs are needed to reach the\n                # $max_nb_chars once\n                while size < max_nb_chars:\n                    paragraph = ('\\n' if size else '') + \\\n                        self.paragraph(ext_word_list=ext_word_list)\n                    text.append(paragraph)\n                    size += len(paragraph)\n                text.pop()\n\n        return \"\".join(text)\n", "path": "faker/providers/lorem/__init__.py"}]}