-
Notifications
You must be signed in to change notification settings - Fork 0
/
optional_faker.py
59 lines (43 loc) · 1.93 KB
/
optional_faker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"""The `optional_faker` sources."""
from __future__ import annotations
import typing as t
from collections.abc import Callable as CallableRuntimeType
import faker.config
from faker.generator import Generator
from faker.providers import BaseProvider
from faker.providers.python import Provider as PythonProvider
if t.TYPE_CHECKING:
import typing_extensions as te
_ANY = t.TypeVar("_ANY", bound=t.Any)
_P = te.ParamSpec("_P")
class Provider(BaseProvider):
"""Faker provider for optional values."""
def __init__(self, generator: Generator) -> None:
"""Declare the other faker providers."""
super().__init__(generator)
self.__python = PythonProvider(generator)
@t.overload
def none_or(self, value: _ANY, /) -> t.Optional[_ANY]:
"""Overload with value."""
@t.overload
def none_or(self, callable: t.Callable[_P, _ANY], /, *args: _P.args, **kwargs: _P.kwargs) -> t.Optional[_ANY]:
"""Overload with callable."""
def none_or(
self, value_or_callable: t.Callable[_P, _ANY], /, *args: _P.args, **kwargs: _P.kwargs
) -> t.Optional[_ANY]:
"""Takes value or callable, and returns the value or the result of the callable, or None.
Args:
value_or_callable: Value or callable to return, if `faker.pybool()` is True.
args: Passed to callable.
kwargs: Passed to callable.
Returns:
`value_or_callable` if value was passed, or callable result if `faker.pybool()` is True. Else - None.
"""
if not self.__python.pybool():
return None
if isinstance(value_or_callable, CallableRuntimeType): # type: ignore[arg-type] # false-positive
return value_or_callable(*args, **kwargs)
else:
return value_or_callable # type: ignore[return-value] # false-positive
optional = none_or # backwards compatibility
faker.config.PROVIDERS.append("optional_faker")