Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve seq helper #247

Merged
merged 2 commits into from Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added

### Changed
- Validate `increment_by` parameter of `seq` helper when `value` is an instance of `datetime` [PR #247](https://github.com/model-bakers/model_bakery/pull/247)
- [dev] Fix some `seq` tests.

### Removed

Expand Down
38 changes: 26 additions & 12 deletions model_bakery/utils.py
Expand Up @@ -10,6 +10,8 @@

from .timezone import tz_aware

__all__ = ["import_from_str", "get_calling_module", "seq"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is not strictly necessary, I think it should not be introduced. The rest of the model_bakery files do not do this (except for gis.py for some reason).



def import_from_str(import_string: Optional[Union[Callable, str]]) -> Any:
"""Import an object defined as import if it is an string.
Expand Down Expand Up @@ -69,11 +71,9 @@ def seq(value, increment_by=1, start=None, suffix=None):
Returns:
object: generated values for sequential data
"""
if type(value) in [datetime.datetime, datetime.date, datetime.time]:
if start:
msg = "start parameter is ignored when using seq with date, time or datetime objects"
warnings.warn(msg)
_validate_sequence_parameters(value, increment_by, start, suffix)

if type(value) in [datetime.datetime, datetime.date, datetime.time]:
if type(value) is datetime.date:
date = datetime.datetime.combine(value, datetime.datetime.now().time())
elif type(value) is datetime.time:
Expand All @@ -93,15 +93,29 @@ def seq(value, increment_by=1, start=None, suffix=None):
else:
yield series_date
else:
if suffix and not isinstance(suffix, str):
raise TypeError("Sequences suffix can only be a string")

for n in itertools.count(start or increment_by, increment_by):
if suffix and not isinstance(value, str):
raise TypeError(
"Sequences with suffix can only be used with text values"
)
elif suffix:
if suffix:
yield value + str(n) + suffix
else:
yield value + type(value)(n)


def _validate_sequence_parameters(value, increment_by, start, suffix) -> None:
if suffix:
if not isinstance(suffix, str):
raise TypeError("Sequences suffix can only be a string")

if not isinstance(value, str):
raise TypeError("Sequences with suffix can only be used with text values")

if type(value) in [datetime.datetime, datetime.date, datetime.time]:
if not isinstance(increment_by, datetime.timedelta):
raise TypeError(
"Sequences with values datetime.datetime, datetime.date and datetime.time, "
"incremente_by must be a datetime.timedelta."
)

if start:
warnings.warn(
"start parameter is ignored when using seq with date, time or datetime objects"
)
35 changes: 25 additions & 10 deletions tests/test_utils.py
Expand Up @@ -76,11 +76,10 @@ def test_string_suffix_and_start(self):
assert next(sequence) == "cookie113@example.com"

def test_string_invalid_suffix(self):
sequence = seq("cookie", suffix=42)

with pytest.raises(TypeError) as exc:
next(sequence)
assert str(exc.value) == "Sequences suffix can only be a string"
next(seq("cookie", suffix=42))

assert str(exc.value) == "Sequences suffix can only be a string"

def test_int(self):
sequence = seq(1)
Expand Down Expand Up @@ -119,13 +118,12 @@ def test_float_increment_by(self):
assert next(sequence) == pytest.approx(6.63)

def test_numbers_with_suffix(self):
sequence = seq(1, suffix="iamnotanumber")
with pytest.raises(TypeError) as exc:
next(sequence)
assert (
str(exc.value)
== "Sequences with suffix can only be used with text values"
)
next(seq(1, suffix="iamnotanumber"))

assert (
str(exc.value) == "Sequences with suffix can only be used with text values"
)

def test_date(self):
sequence = seq(
Expand Down Expand Up @@ -162,3 +160,20 @@ def test_datetime(self, settings, use_tz):
assert next(sequence) == datetime.datetime(
2021, 2, 12, 00, 39, 58, 457698
).replace(tzinfo=tzinfo)

@pytest.mark.parametrize(
"value",
[
datetime.datetime(2021, 2, 11, 15, 39, 58, 457698),
datetime.date(2021, 2, 11),
datetime.time(15, 39, 58, 457698),
],
)
def test_should_raise_exception_for_datetime_instances(self, value):
with pytest.raises(TypeError) as exc:
next(seq(value))

assert str(exc.value) == (
"Sequences with values datetime.datetime, datetime.date and datetime.time, "
"incremente_by must be a datetime.timedelta."
)