Right now we use something like:
def price_in_btc(self, minimum: float = 0, maximum: float = 2) -> str:
"""Generate random price in BTC.
:param minimum: Minimum value of price
:param maximum: Maximum value of price.
:return: Price in BTC.
:Example:
0.5885238 BTC
"""
I suggest to change it to:
def price_in_btc(self, minimum: float = 0, maximum: float = 2) -> str:
"""Generate random price in BTC.
:param minimum: Minimum value of price
:param maximum: Maximum value of price.
:return: Price in BTC.
>>> from mimesis import Business
>>> provider = Business()
>>> provider.price_in_btc()
0.5885238 BTC
"""
https://docs.python.org/3/library/doctest.html
But we need to freeze random here.
So, it possible to use something like https://docs.pytest.org/en/latest/doctest.html#the-doctest-namespace-fixture
@sobolevn I'm all for it.
@sobolevn Hello! Can you please clarify where exactly we want to see this action? after make test command ?
I want to write doctests instead of static examples. They will be executed with pytest --doctest-modules
One more question! Why it's necessary to freeze random? I think it's more useful to see that function provides different numbers as it was conceived.
@Valerievich we do not need to freeze it, just seed is enough.
This issue can be closed. We've done with PR.
@Valerievich but you have changed only a single example.
My original idea was to change all examples to the doctests. In all project.
@Valerievich Yeah, I don't understand why we need to close this too.
Ok. Now I understand the whole idea of this issue. I am going to continue to work on this. It makes sense to create PR's which consist of changes only for one provider I think. It would be easier to approve.
@Valerievich agreed.
I see that my changes in Business provider doctest was removed in this commit. I understand that doctest might be useless.
Does it mean that issue isn't relevant anymore?
I'd like to implement this feature because I am a big fan of doctest.
I think that there are three different ways to resolve the problem of the randomness:
home() of the path.py module is deterministic so its docstring could be written as:def home(self) -> str:
r"""Generate a home path.
:return: Home path.
>>> p = Path('linux')
>>> p.home()
'/home'
>>> p = Path('win32')
>>> p.home()
'C:\\Users'
"""
return str(self._pathlib_home)
I don't think that this option will increase the quality of the docstrings because I suspect that the number of deterministic functions is very low
def name(self, gender: Optional[Gender] = None) -> str:
"""Generate a random name.
:param gender: Gender's enum object.
:return: Name.
>>> p = Person(seed=0)
>>> p.name()
'Ned'
"""
I think that this option is the best one, but I'm not completely sure that this method will work. In other words I am not sure that the function name() with seed=0 will always return 'Ned'.
def name(self, gender: Optional[Gender] = None) -> str:
"""Generate a random name.
:param gender: Gender's enum object.
:return: Name.
>>> p = Person(seed=0)
>>> name = p.name()
>>> name in person._data['names']['male']
"""
This one will work but I think that is not a very clear example to write in a docstring.
@sobolevn @lk-geimfari please let me know and I will work on it!
@ceccoemi I am a big fan of doctests too!
I imagine that this can be solved by combining different ways.
pytest fixture and random.seed functionI guess that the way to go.
@sobolevn yes!
It seems that this fixture will produce deterministic doctests.
I have made a little test with
@pytest.fixture(autouse=True)
def seeded_doctest(doctest_namespace):
import mimesis
mimesis.random.random.seed('mimesis')
doctest_namespace['mimesis'] = mimesis
in conftest.py and it seems to work!
The doctests will look like this:
def name(self, gender: Optional[Gender] = None) -> str:
"""Generate a random name.
:param gender: Gender's enum object.
:return: Name.
>>> p = mimesis.Person()
>>> p.name()
'Catarina'
"""
In the weekend I will start to convert all the examples to doctests if you agree.
@ceccoemi We used to try to resolve this issue. I remember that this is problematic because of possible updates of files (JSON files where we store data for each provider).
In this case we can patch random to alway return 1 for example.
And this will solve all issues.
Writing a fixture like this
@pytest.fixture(autouse=True)
def seeded_doctest(doctest_namespace):
import mimesis
mimesis.random.random.random = lambda: 0
doctest_namespace['mimesis'] = mimesis
will break other tests.
I think that the only way is to seed the random module and check its output. If you are worried about the updates of the JSON files never mind, we leave the examples as they are without doctest.
Most helpful comment
Ok. Now I understand the whole idea of this issue. I am going to continue to work on this. It makes sense to create PR's which consist of changes only for one provider I think. It would be easier to approve.