Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/faker/providers/__init__.py: 42%
128 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1import re
2import string
4from collections import OrderedDict
5from typing import Any, Collection, List, Optional, Sequence, TypeVar, Union
7from ..generator import Generator
8from ..typing import OrderedDictType
9from ..utils.distribution import choices_distribution, choices_distribution_unique
11_re_hash = re.compile(r"#")
12_re_perc = re.compile(r"%")
13_re_excl = re.compile(r"!")
14_re_at = re.compile(r"@")
15_re_qm = re.compile(r"\?")
16_re_cir = re.compile(r"\^")
18T = TypeVar("T")
19ElementsType = Union[Collection[str], Collection[T], OrderedDictType[T, float]]
22class BaseProvider:
24 __provider__ = "base"
25 __lang__: Optional[str] = None
26 __use_weighting__ = False
28 # Locales supported by Linux Mint from `/usr/share/i18n/SUPPORTED`
29 language_locale_codes = {
30 "aa": ("DJ", "ER", "ET"),
31 "af": ("ZA",),
32 "ak": ("GH",),
33 "am": ("ET",),
34 "an": ("ES",),
35 "apn": ("IN",),
36 "ar": (
37 "AE",
38 "BH",
39 "DJ",
40 "DZ",
41 "EG",
42 "EH",
43 "ER",
44 "IL",
45 "IN",
46 "IQ",
47 "JO",
48 "KM",
49 "KW",
50 "LB",
51 "LY",
52 "MA",
53 "MR",
54 "OM",
55 "PS",
56 "QA",
57 "SA",
58 "SD",
59 "SO",
60 "SS",
61 "SY",
62 "TD",
63 "TN",
64 "YE",
65 ),
66 "as": ("IN",),
67 "ast": ("ES",),
68 "ayc": ("PE",),
69 "az": ("AZ", "IN"),
70 "be": ("BY",),
71 "bem": ("ZM",),
72 "ber": ("DZ", "MA"),
73 "bg": ("BG",),
74 "bhb": ("IN",),
75 "bho": ("IN",),
76 "bn": ("BD", "IN"),
77 "bo": ("CN", "IN"),
78 "br": ("FR",),
79 "brx": ("IN",),
80 "bs": ("BA",),
81 "byn": ("ER",),
82 "ca": ("AD", "ES", "FR", "IT"),
83 "ce": ("RU",),
84 "ckb": ("IQ",),
85 "cmn": ("TW",),
86 "crh": ("UA",),
87 "cs": ("CZ",),
88 "csb": ("PL",),
89 "cv": ("RU",),
90 "cy": ("GB",),
91 "da": ("DK",),
92 "de": ("AT", "BE", "CH", "DE", "LI", "LU"),
93 "doi": ("IN",),
94 "dv": ("MV",),
95 "dz": ("BT",),
96 "el": ("GR", "CY"),
97 "en": (
98 "AG",
99 "AU",
100 "BW",
101 "CA",
102 "DK",
103 "GB",
104 "HK",
105 "IE",
106 "IN",
107 "NG",
108 "NZ",
109 "PH",
110 "SG",
111 "US",
112 "ZA",
113 "ZM",
114 "ZW",
115 ),
116 "eo": ("US",),
117 "es": (
118 "AR",
119 "BO",
120 "CL",
121 "CO",
122 "CR",
123 "CU",
124 "DO",
125 "EC",
126 "ES",
127 "GT",
128 "HN",
129 "MX",
130 "NI",
131 "PA",
132 "PE",
133 "PR",
134 "PY",
135 "SV",
136 "US",
137 "UY",
138 "VE",
139 ),
140 "et": ("EE",),
141 "eu": ("ES", "FR"),
142 "fa": ("IR",),
143 "ff": ("SN",),
144 "fi": ("FI",),
145 "fil": ("PH",),
146 "fo": ("FO",),
147 "fr": ("CA", "CH", "FR", "LU"),
148 "fur": ("IT",),
149 "fy": ("NL", "DE"),
150 "ga": ("IE",),
151 "gd": ("GB",),
152 "gez": ("ER", "ET"),
153 "gl": ("ES",),
154 "gu": ("IN",),
155 "gv": ("GB",),
156 "ha": ("NG",),
157 "hak": ("TW",),
158 "he": ("IL",),
159 "hi": ("IN",),
160 "hne": ("IN",),
161 "hr": ("HR",),
162 "hsb": ("DE",),
163 "ht": ("HT",),
164 "hu": ("HU",),
165 "hy": ("AM",),
166 "ia": ("FR",),
167 "id": ("ID",),
168 "ig": ("NG",),
169 "ik": ("CA",),
170 "is": ("IS",),
171 "it": ("CH", "IT"),
172 "iu": ("CA",),
173 "iw": ("IL",),
174 "ja": ("JP",),
175 "ka": ("GE",),
176 "kk": ("KZ",),
177 "kl": ("GL",),
178 "km": ("KH",),
179 "kn": ("IN",),
180 "ko": ("KR",),
181 "kok": ("IN",),
182 "ks": ("IN",),
183 "ku": ("TR",),
184 "kw": ("GB",),
185 "ky": ("KG",),
186 "lb": ("LU",),
187 "lg": ("UG",),
188 "li": ("BE", "NL"),
189 "lij": ("IT",),
190 "ln": ("CD",),
191 "lo": ("LA",),
192 "lt": ("LT",),
193 "lv": ("LV",),
194 "lzh": ("TW",),
195 "mag": ("IN",),
196 "mai": ("IN",),
197 "mg": ("MG",),
198 "mhr": ("RU",),
199 "mi": ("NZ",),
200 "mk": ("MK",),
201 "ml": ("IN",),
202 "mn": ("MN",),
203 "mni": ("IN",),
204 "mr": ("IN",),
205 "ms": ("MY",),
206 "mt": ("MT",),
207 "my": ("MM",),
208 "nan": ("TW",),
209 "nb": ("NO",),
210 "nds": ("DE", "NL"),
211 "ne": ("NP",),
212 "nhn": ("MX",),
213 "niu": ("NU", "NZ"),
214 "nl": ("AW", "BE", "NL"),
215 "nn": ("NO",),
216 "nr": ("ZA",),
217 "nso": ("ZA",),
218 "oc": ("FR",),
219 "om": ("ET", "KE"),
220 "or": ("IN",),
221 "os": ("RU",),
222 "pa": ("IN", "PK"),
223 "pap": ("AN", "AW", "CW"),
224 "pl": ("PL",),
225 "ps": ("AF",),
226 "pt": ("BR", "PT"),
227 "quz": ("PE",),
228 "raj": ("IN",),
229 "ro": ("RO",),
230 "ru": ("RU", "UA"),
231 "rw": ("RW",),
232 "sa": ("IN",),
233 "sat": ("IN",),
234 "sc": ("IT",),
235 "sd": ("IN", "PK"),
236 "se": ("NO",),
237 "shs": ("CA",),
238 "si": ("LK",),
239 "sid": ("ET",),
240 "sk": ("SK",),
241 "sl": ("SI",),
242 "so": ("DJ", "ET", "KE", "SO"),
243 "sq": ("AL", "ML"),
244 "sr": ("ME", "RS"),
245 "ss": ("ZA",),
246 "st": ("ZA",),
247 "sv": ("FI", "SE"),
248 "sw": ("KE", "TZ"),
249 "szl": ("PL",),
250 "ta": ("IN", "LK"),
251 "tcy": ("IN",),
252 "te": ("IN",),
253 "tg": ("TJ",),
254 "th": ("TH",),
255 "the": ("NP",),
256 "ti": ("ER", "ET"),
257 "tig": ("ER",),
258 "tk": ("TM",),
259 "tl": ("PH",),
260 "tn": ("ZA",),
261 "tr": ("CY", "TR"),
262 "ts": ("ZA",),
263 "tt": ("RU",),
264 "ug": ("CN",),
265 "uk": ("UA",),
266 "unm": ("US",),
267 "ur": ("IN", "PK"),
268 "uz": ("UZ",),
269 "ve": ("ZA",),
270 "vi": ("VN",),
271 "wa": ("BE",),
272 "wae": ("CH",),
273 "wal": ("ET",),
274 "wo": ("SN",),
275 "xh": ("ZA",),
276 "yi": ("US",),
277 "yo": ("NG",),
278 "yue": ("HK",),
279 "zh": ("CN", "HK", "SG", "TW"),
280 "zu": ("ZA",),
281 }
283 def __init__(self, generator: Any) -> None:
284 """
285 Base class for fake data providers
286 :param generator: `Generator` instance
287 """
288 self.generator = generator
290 def locale(self) -> str:
291 """Generate a random underscored i18n locale code (e.g. en_US)."""
293 language_code = self.language_code()
294 return (
295 language_code
296 + "_"
297 + self.random_element(
298 BaseProvider.language_locale_codes[language_code],
299 )
300 )
302 def language_code(self) -> str:
303 """Generate a random i18n language code (e.g. en)."""
305 return self.random_element(BaseProvider.language_locale_codes.keys())
307 def random_int(self, min: int = 0, max: int = 9999, step: int = 1) -> int:
308 """Generate a random integer between two integers ``min`` and ``max`` inclusive
309 while observing the provided ``step`` value.
311 This method is functionally equivalent to randomly sampling an integer
312 from the sequence ``range(min, max + 1, step)``.
314 :sample: min=0, max=15
315 :sample: min=0, max=15, step=3
316 """
317 return self.generator.random.randrange(min, max + 1, step)
319 def random_digit(self) -> int:
320 """Generate a random digit (0 to 9)."""
322 return self.generator.random.randint(0, 9)
324 def random_digit_not_null(self) -> int:
325 """Generate a random non-zero digit (1 to 9)."""
327 return self.generator.random.randint(1, 9)
329 def random_digit_or_empty(self) -> Union[int, str]:
330 """Generate a random digit (0 to 9) or an empty string.
332 This method will return an empty string 50% of the time,
333 and each digit has a 1/20 chance of being generated.
334 """
336 if self.generator.random.randint(0, 1):
337 return self.generator.random.randint(0, 9)
338 else:
339 return ""
341 def random_digit_not_null_or_empty(self) -> Union[int, str]:
342 """Generate a random non-zero digit (1 to 9) or an empty string.
344 This method will return an empty string 50% of the time,
345 and each digit has a 1/18 chance of being generated.
346 """
348 if self.generator.random.randint(0, 1):
349 return self.generator.random.randint(1, 9)
350 else:
351 return ""
353 def random_number(self, digits: Optional[int] = None, fix_len: bool = False) -> int:
354 """Generate a random integer according to the following rules:
356 - If ``digits`` is ``None`` (default), its value will be set to a random
357 integer from 1 to 9.
358 - If ``fix_len`` is ``False`` (default), all integers that do not exceed
359 the number of ``digits`` can be generated.
360 - If ``fix_len`` is ``True``, only integers with the exact number of
361 ``digits`` can be generated.
363 :sample: fix_len=False
364 :sample: fix_len=True
365 :sample: digits=3
366 :sample: digits=3, fix_len=False
367 :sample: digits=3, fix_len=True
368 """
369 if digits is None:
370 digits = self.random_digit_not_null()
371 if digits < 0:
372 raise ValueError("The digit parameter must be greater than or equal to 0.")
373 if fix_len:
374 if digits > 0:
375 return self.generator.random.randint(pow(10, digits - 1), pow(10, digits) - 1)
376 else:
377 raise ValueError("A number of fixed length cannot have less than 1 digit in it.")
378 else:
379 return self.generator.random.randint(0, pow(10, digits) - 1)
381 def random_letter(self) -> str:
382 """Generate a random ASCII letter (a-z and A-Z)."""
384 return self.generator.random.choice(getattr(string, "letters", string.ascii_letters))
386 def random_letters(self, length: int = 16) -> Sequence[str]:
387 """Generate a list of random ASCII letters (a-z and A-Z) of the specified ``length``.
389 :sample: length=10
390 """
391 return self.random_choices(
392 getattr(string, "letters", string.ascii_letters),
393 length=length,
394 )
396 def random_lowercase_letter(self) -> str:
397 """Generate a random lowercase ASCII letter (a-z)."""
399 return self.generator.random.choice(string.ascii_lowercase)
401 def random_uppercase_letter(self) -> str:
402 """Generate a random uppercase ASCII letter (A-Z)."""
404 return self.generator.random.choice(string.ascii_uppercase)
406 def random_elements(
407 self,
408 elements: ElementsType[T] = ("a", "b", "c"), # type: ignore[assignment]
409 length: Optional[int] = None,
410 unique: bool = False,
411 use_weighting: Optional[bool] = None,
412 ) -> Sequence[T]:
413 """Generate a list of randomly sampled objects from ``elements``.
415 Set ``unique`` to ``False`` for random sampling with replacement, and set ``unique`` to
416 ``True`` for random sampling without replacement.
418 If ``length`` is set to ``None`` or is omitted, ``length`` will be set to a random
419 integer from 1 to the size of ``elements``.
421 The value of ``length`` cannot be greater than the number of objects
422 in ``elements`` if ``unique`` is set to ``True``.
424 The value of ``elements`` can be any sequence type (``list``, ``tuple``, ``set``,
425 ``string``, etc) or an ``OrderedDict`` type. If it is the latter, the keys will be
426 used as the objects for sampling, and the values will be used as weighted probabilities
427 if ``unique`` is set to ``False``. For example:
429 .. code-block:: python
431 # Random sampling with replacement
432 fake.random_elements(
433 elements=OrderedDict([
434 ("variable_1", 0.5), # Generates "variable_1" 50% of the time
435 ("variable_2", 0.2), # Generates "variable_2" 20% of the time
436 ("variable_3", 0.2), # Generates "variable_3" 20% of the time
437 ("variable_4": 0.1), # Generates "variable_4" 10% of the time
438 ]), unique=False
439 )
441 # Random sampling without replacement (defaults to uniform distribution)
442 fake.random_elements(
443 elements=OrderedDict([
444 ("variable_1", 0.5),
445 ("variable_2", 0.2),
446 ("variable_3", 0.2),
447 ("variable_4": 0.1),
448 ]), unique=True
449 )
451 :sample: elements=('a', 'b', 'c', 'd'), unique=False
452 :sample: elements=('a', 'b', 'c', 'd'), unique=True
453 :sample: elements=('a', 'b', 'c', 'd'), length=10, unique=False
454 :sample: elements=('a', 'b', 'c', 'd'), length=4, unique=True
455 :sample: elements=OrderedDict([
456 ("a", 0.45),
457 ("b", 0.35),
458 ("c", 0.15),
459 ("d", 0.05),
460 ]), length=20, unique=False
461 :sample: elements=OrderedDict([
462 ("a", 0.45),
463 ("b", 0.35),
464 ("c", 0.15),
465 ("d", 0.05),
466 ]), unique=True
467 """
468 use_weighting = use_weighting if use_weighting is not None else self.__use_weighting__
470 if isinstance(elements, dict) and not isinstance(elements, OrderedDict): 470 ↛ 471line 470 didn't jump to line 471, because the condition on line 470 was never true
471 raise ValueError("Use OrderedDict only to avoid dependency on PYTHONHASHSEED (See #363).")
473 fn = choices_distribution_unique if unique else choices_distribution
475 if length is None: 475 ↛ 476line 475 didn't jump to line 476, because the condition on line 475 was never true
476 length = self.generator.random.randint(1, len(elements))
478 if unique and length > len(elements): 478 ↛ 479line 478 didn't jump to line 479, because the condition on line 478 was never true
479 raise ValueError("Sample length cannot be longer than the number of unique elements to pick from.")
481 if isinstance(elements, dict):
482 if not hasattr(elements, "_key_cache"):
483 elements._key_cache = tuple(elements.keys()) # type: ignore
485 choices = elements._key_cache # type: ignore[attr-defined, union-attr]
486 probabilities = tuple(elements.values()) if use_weighting else None
487 else:
488 if unique: 488 ↛ 490line 488 didn't jump to line 490, because the condition on line 488 was never true
489 # shortcut
490 return self.generator.random.sample(elements, length)
491 choices = elements
492 probabilities = None
494 return fn(
495 tuple(choices),
496 probabilities,
497 self.generator.random,
498 length=length,
499 )
501 def random_choices(
502 self,
503 elements: ElementsType[T] = ("a", "b", "c"), # type: ignore[assignment]
504 length: Optional[int] = None,
505 ) -> Sequence[T]:
506 """Generate a list of objects randomly sampled from ``elements`` with replacement.
508 For information on the ``elements`` and ``length`` arguments, please refer to
509 :meth:`random_elements() <faker.providers.BaseProvider.random_elements>` which
510 is used under the hood with the ``unique`` argument explicitly set to ``False``.
512 :sample: elements=('a', 'b', 'c', 'd')
513 :sample: elements=('a', 'b', 'c', 'd'), length=10
514 :sample: elements=OrderedDict([
515 ("a", 0.45),
516 ("b", 0.35),
517 ("c", 0.15),
518 ("d", 0.05),
519 ])
520 :sample: elements=OrderedDict([
521 ("a", 0.45),
522 ("b", 0.35),
523 ("c", 0.15),
524 ("d", 0.05),
525 ]), length=20
526 """
527 return self.random_elements(elements, length, unique=False)
529 def random_element(self, elements: ElementsType[T] = ("a", "b", "c")) -> T:
530 """Generate a randomly sampled object from ``elements``.
532 For information on the ``elements`` argument, please refer to
533 :meth:`random_elements() <faker.providers.BaseProvider.random_elements>` which
534 is used under the hood with the ``unique`` argument set to ``False`` and the
535 ``length`` argument set to ``1``.
537 :sample: elements=('a', 'b', 'c', 'd')
538 :sample size=10: elements=OrderedDict([
539 ("a", 0.45),
540 ("b", 0.35),
541 ("c", 0.15),
542 ("d", 0.05),
543 ])
544 """
546 return self.random_elements(elements, length=1)[0]
548 def random_sample(
549 self, elements: ElementsType[T] = ("a", "b", "c"), length: Optional[int] = None # type: ignore[assignment]
550 ) -> Sequence[T]:
551 """Generate a list of objects randomly sampled from ``elements`` without replacement.
553 For information on the ``elements`` and ``length`` arguments, please refer to
554 :meth:`random_elements() <faker.providers.BaseProvider.random_elements>` which
555 is used under the hood with the ``unique`` argument explicitly set to ``True``.
557 :sample: elements=('a', 'b', 'c', 'd', 'e', 'f')
558 :sample: elements=('a', 'b', 'c', 'd', 'e', 'f'), length=3
559 """
560 return self.random_elements(elements, length, unique=True)
562 def randomize_nb_elements(
563 self,
564 number: int = 10,
565 le: bool = False,
566 ge: bool = False,
567 min: Optional[int] = None,
568 max: Optional[int] = None,
569 ) -> int:
570 """Generate a random integer near ``number`` according to the following rules:
572 - If ``le`` is ``False`` (default), allow generation up to 140% of ``number``.
573 If ``True``, upper bound generation is capped at 100%.
574 - If ``ge`` is ``False`` (default), allow generation down to 60% of ``number``.
575 If ``True``, lower bound generation is capped at 100%.
576 - If a numerical value for ``min`` is provided, generated values less than ``min``
577 will be clamped at ``min``.
578 - If a numerical value for ``max`` is provided, generated values greater than
579 ``max`` will be clamped at ``max``.
580 - If both ``le`` and ``ge`` are ``True``, the value of ``number`` will automatically
581 be returned, regardless of the values supplied for ``min`` and ``max``.
583 :sample: number=100
584 :sample: number=100, ge=True
585 :sample: number=100, ge=True, min=120
586 :sample: number=100, le=True
587 :sample: number=100, le=True, max=80
588 :sample: number=79, le=True, ge=True, min=80
589 """
590 if le and ge:
591 return number
592 _min = 100 if ge else 60
593 _max = 100 if le else 140
594 nb = int(number * self.generator.random.randint(_min, _max) / 100)
595 if min is not None and nb < min:
596 nb = min
597 if max is not None and nb > max:
598 nb = max
599 return nb
601 def numerify(self, text: str = "###") -> str:
602 """Generate a string with each placeholder in ``text`` replaced according
603 to the following rules:
605 - Number signs ('#') are replaced with a random digit (0 to 9).
606 - Percent signs ('%') are replaced with a random non-zero digit (1 to 9).
607 - Exclamation marks ('!') are replaced with a random digit or an empty string.
608 - At symbols ('@') are replaced with a random non-zero digit or an empty string.
610 Under the hood, this method uses :meth:`random_digit() <faker.providers.BaseProvider.random_digit>`,
611 :meth:`random_digit_not_null() <faker.providers.BaseProvider.random_digit_not_null>`,
612 :meth:`random_digit_or_empty() <faker.providers.BaseProvider.random_digit_or_empty>`,
613 and :meth:`random_digit_not_null_or_empty() <faker.providers.BaseProvider.random_digit_not_null_or_empty>`
614 to generate the random values.
616 :sample: text='Intel Core i%-%%##K vs AMD Ryzen % %%##X'
617 :sample: text='!!! !!@ !@! !@@ @!! @!@ @@! @@@'
618 """
619 text = _re_hash.sub(lambda x: str(self.random_digit()), text)
620 text = _re_perc.sub(lambda x: str(self.random_digit_not_null()), text)
621 text = _re_excl.sub(lambda x: str(self.random_digit_or_empty()), text)
622 text = _re_at.sub(lambda x: str(self.random_digit_not_null_or_empty()), text)
623 return text
625 def lexify(self, text: str = "????", letters: str = string.ascii_letters) -> str:
626 """Generate a string with each question mark ('?') in ``text``
627 replaced with a random character from ``letters``.
629 By default, ``letters`` contains all ASCII letters, uppercase and lowercase.
631 :sample: text='Random Identifier: ??????????'
632 :sample: text='Random Identifier: ??????????', letters='ABCDE'
633 """
634 return _re_qm.sub(lambda x: self.random_element(letters), text)
636 def bothify(self, text: str = "## ??", letters: str = string.ascii_letters) -> str:
637 """Generate a string with each placeholder in ``text`` replaced according to the following rules:
639 - Number signs ('#') are replaced with a random digit (0 to 9).
640 - Question marks ('?') are replaced with a random character from ``letters``.
642 By default, ``letters`` contains all ASCII letters, uppercase and lowercase.
644 Under the hood, this method uses :meth:`numerify() <faker.providers.BaseProvider.numerify>` and
645 and :meth:`lexify() <faker.providers.BaseProvider.lexify>` to generate random values for number
646 signs and question marks respectively.
648 :sample: letters='ABCDE'
649 :sample: text='Product Number: ????-########'
650 :sample: text='Product Number: ????-########', letters='ABCDE'
651 """
652 return self.lexify(self.numerify(text), letters=letters)
654 def hexify(self, text: str = "^^^^", upper: bool = False) -> str:
655 """Generate a string with each circumflex ('^') in ``text``
656 replaced with a random hexadecimal character.
658 By default, ``upper`` is set to False. If set to ``True``, output
659 will be formatted using uppercase hexadecimal characters.
661 :sample: text='MAC Address: ^^:^^:^^:^^:^^:^^'
662 :sample: text='MAC Address: ^^:^^:^^:^^:^^:^^', upper=True
663 """
664 letters = string.hexdigits[:-6]
665 if upper:
666 letters = letters.upper()
667 return _re_cir.sub(lambda x: self.random_element(letters), text)
670class DynamicProvider(BaseProvider):
671 def __init__(
672 self,
673 provider_name: str,
674 elements: Optional[List] = None,
675 generator: Optional[Any] = None,
676 ):
677 """
678 A faker Provider capable of getting a list of elements to randomly select from,
679 instead of using the predefined list of elements which exist in the default providers in faker.
681 :param provider_name: Name of provider, which would translate into the function name e.g. faker.my_fun().
682 :param elements: List of values to randomly select from
683 :param generator: Generator object. If missing, the default Generator is used.
685 :example:
686 >>>from faker import Faker
687 >>>from faker.providers import DynamicProvider
689 >>>medical_professions_provider = DynamicProvider(
690 >>> provider_name="medical_profession",
691 >>> elements=["dr.", "doctor", "nurse", "surgeon", "clerk"],
692 >>>)
693 >>>fake = Faker()
694 >>>fake.add_provider(medical_professions_provider)
696 >>>fake.medical_profession()
697 "dr."
699 """
701 if not generator:
702 generator = Generator()
703 super().__init__(generator)
704 if provider_name.startswith("__"):
705 raise ValueError("Provider name cannot start with __ as it would be ignored by Faker")
707 self.provider_name = provider_name
709 self.elements = []
710 if elements:
711 self.elements = elements
713 setattr(self, provider_name, self.get_random_value) # Add a method for the provider_name value
715 def add_element(self, element: str) -> None:
716 """Add new element."""
717 self.elements.append(element)
719 def get_random_value(self) -> Any:
721 if not self.elements or len(self.elements) == 0:
722 raise ValueError("Elements should be a list of values the provider samples from")
724 return self.random_element(self.elements)