Skip to content

Commit e87d20a

Browse files
committed
Version 13.1.0
1 parent f7c5e5b commit e87d20a

File tree

7 files changed

+80
-60
lines changed

7 files changed

+80
-60
lines changed

CHANGELOG.rst

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
Version 13.1.0
2+
--------------
3+
4+
- Removed the `age()` and `work_experience()` methods from the `Person` provider. Use ``person.random.randint()`` instead.
5+
- Fixed type hints for `Generic`. (See `#1470 <https://github.com/lk-geimfari/mimesis/issues/1471>`_).
6+
- Added the `birthdate()` method to the `Person` provider. (See `#1470 <https://github.com/lk-geimfari/mimesis/issues/1470>`_).
7+
18
Version 13.0.0
29
--------------
310

docs/conf.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@
7070
# built documents.
7171
#
7272
# The short X.Y version.
73-
version = "13.0"
73+
version = "13.1"
7474
# The full version, including alpha/beta/rc tags.
75-
release = "13.0.0"
75+
release = "13.1.0"
7676

7777
# The language for content autogenerated by Sphinx. Refer to documentation
7878
# for a list of supported languages.

mimesis/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
"__license__",
147147
]
148148

149-
__version__ = "13.0.0"
149+
__version__ = "13.1.0"
150150
__title__ = "mimesis"
151151
__description__ = "Mimesis: Fake Data Generator."
152152
__url__ = "https://github.com/lk-geimfari/mimesis"

mimesis/providers/person.py

+41-22
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import re
55
import typing as t
66
import uuid
7+
from datetime import date, datetime
78
from string import ascii_letters, digits, punctuation
89

910
from mimesis.data import (
@@ -16,6 +17,7 @@
1617
)
1718
from mimesis.enums import Gender, TitleType
1819
from mimesis.providers.base import BaseDataProvider
20+
from mimesis.types import Date
1921

2022
__all__ = ["Person"]
2123

@@ -30,39 +32,56 @@ def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
3032
:param seed: Seed.
3133
"""
3234
super().__init__(*args, **kwargs)
33-
self._store = {
34-
"age": 0,
35-
}
3635

3736
class Meta:
3837
name = "person"
3938
datafile = f"{name}.json"
4039

41-
def age(self, minimum: int = 16, maximum: int = 66) -> int:
42-
"""Generates a random age of a person.
40+
def _validate_birth_year_params(self, min_year: int, max_year: int) -> None:
41+
if min_year > max_year:
42+
raise ValueError("min_year must be less than or equal to max_year")
4343

44-
:param maximum: Maximum value of age.
45-
:param minimum: Minimum value of age.
46-
:return: Random integer.
44+
if min_year < 1900:
45+
raise ValueError("min_year must be greater than or equal to 1900")
4746

48-
:Example:
49-
23.
50-
"""
51-
age = self.random.randint(minimum, maximum)
52-
self._store["age"] = age
53-
return age
47+
if max_year > datetime.now().year:
48+
raise ValueError(
49+
"The max_year must be less than or equal to the current year"
50+
)
51+
52+
def _is_leap_year(self, year: int) -> bool:
53+
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
5454

55-
def work_experience(self, working_start_age: int = 22) -> int:
56-
"""Generates a random work experience.
55+
def birthdate(self, min_year: int = 1980, max_year: int = 2023) -> Date:
56+
"""Generates a random birthdate as a :py:class:`datetime.date` object.
5757
58-
:param working_start_age: Age then person start to work.
59-
:return: Depend on previous generated age.
58+
:param min_year: Maximum birth year.
59+
:param max_year: Minimum birth year.
60+
:return: Random date object.
6061
"""
61-
age = self._store["age"]
62-
if age == 0:
63-
age = self.age()
62+
self._validate_birth_year_params(min_year, max_year)
63+
year = self.random.randint(min_year, max_year)
64+
feb_days = 29 if self._is_leap_year(year) else 28
65+
66+
month_days_map = {
67+
1: 31,
68+
2: feb_days,
69+
3: 31,
70+
4: 30,
71+
5: 31,
72+
6: 30,
73+
7: 31,
74+
8: 31,
75+
9: 30,
76+
10: 31,
77+
11: 30,
78+
12: 31,
79+
}
6480

65-
return max(age - working_start_age, 0)
81+
month = self.random.randint(1, 12)
82+
max_day = month_days_map[month]
83+
day = self.random.randint(1, max_day)
84+
return date(year=year, month=month, day=day)
6685

6786
def name(self, gender: Gender | None = None) -> str:
6887
"""Generates a random name.

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "mimesis"
3-
version = "13.0.0"
3+
version = "13.1.0"
44
description = "Mimesis: Fake Data Generator."
55
authors = ["Isaak Uchakaev <[email protected]>"]
66
license = "MIT"

tests/test_providers/test_generic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ def test_generic_payment(self, g1, g2):
198198
assert g1.payment.paypal() == g2.payment.paypal()
199199

200200
def test_generic_person(self, g1, g2):
201-
assert g1.person.age() == g2.person.age()
201+
assert g1.person.birthdate() == g2.person.birthdate()
202202
assert g1.person.name() == g2.person.name()
203203

204204
def test_generic_science(self, g1, g2):

tests/test_providers/test_person.py

+27-33
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import re
2+
from datetime import date, datetime
23

34
import pytest
45

@@ -19,36 +20,31 @@ def test_str(self, person):
1920
assert re.match(patterns.DATA_PROVIDER_STR_REGEX, str(person))
2021

2122
@pytest.mark.parametrize(
22-
"minimum, maximum",
23+
"min_year, max_year",
2324
[
24-
(16, 18),
25-
(18, 21),
26-
(22, 28),
25+
(1900, 1950),
26+
(1951, 2001),
27+
(2001, 2023),
2728
],
2829
)
29-
def test_age(self, _person, minimum, maximum):
30-
result = _person.age(minimum, maximum)
31-
assert (result >= minimum) and (result <= maximum)
30+
def test_birthdate(self, _person, min_year, max_year):
31+
birthdate = _person.birthdate(min_year, max_year)
32+
assert min_year <= birthdate.year <= max_year
33+
assert isinstance(birthdate, date)
3234

33-
def test_age_store(self, _person):
34-
result = _person._store["age"]
35-
assert result == 0
36-
37-
def test_age_update(self, _person):
38-
result = _person.age() - _person._store["age"]
39-
assert result == 0
40-
41-
def test_work_experience(self, _person):
42-
result = _person.work_experience(working_start_age=0) - _person._store["age"]
43-
assert result == 0
44-
45-
def test_work_experience_store(self, _person):
46-
result = _person.work_experience() - _person.work_experience()
47-
assert result == 0
35+
@pytest.mark.parametrize(
36+
"min_year, max_year",
37+
[
38+
(1899, 1950),
39+
(datetime.now().year + 1, datetime.now().year + 3),
40+
],
41+
)
42+
def test_birthdate_with_invalid_params(self, _person, min_year, max_year):
43+
with pytest.raises(ValueError):
44+
_person.birthdate(min_year, max_year)
4845

49-
def test_work_experience_extreme(self, _person):
50-
result = _person.work_experience(working_start_age=100000)
51-
assert result == 0
46+
def test_is_leap_year(self, _person):
47+
assert _person._is_leap_year(2024)
5248

5349
def test_password(self, _person):
5450
result = _person.password(length=15)
@@ -344,14 +340,6 @@ def p1(self, seed):
344340
def p2(self, seed):
345341
return Person(seed=seed)
346342

347-
def test_age(self, p1, p2):
348-
assert p1.age() == p2.age()
349-
assert p1.age(12, 42) == p2.age(12, 42)
350-
351-
def test_work_experience(self, p1, p2):
352-
assert p1.work_experience() == p2.work_experience()
353-
assert p1.work_experience(19) == p2.work_experience(19)
354-
355343
def test_password(self, p1, p2):
356344
assert p1.password() == p2.password()
357345
assert p1.password(length=12, hashed=True) == p2.password(
@@ -413,6 +401,12 @@ def test_full_name(self, p1, p2):
413401
def test_gender_code(self, p1, p2):
414402
assert p1.gender_code() == p2.gender_code()
415403

404+
def test_birthdate(self, p1, p2):
405+
assert p1.birthdate() == p2.birthdate()
406+
assert p1.birthdate(min_year=1900, max_year=2023) == p2.birthdate(
407+
min_year=1900, max_year=2023
408+
)
409+
416410
def test_gender_symbol(self, p1, p2):
417411
assert p1.gender_symbol() == p2.gender_symbol()
418412

0 commit comments

Comments
 (0)