Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ ChangeLog

- Add support for Django 5.2

*New:*

- :issue:`961`: Add :class:`~factory.fuzzy.FuzzyFunction`, a correctly named
counterpart to :class:`~factory.fuzzy.FuzzyAttribute`.

*Deprecated:*

- :issue:`961`: :class:`~factory.fuzzy.FuzzyAttribute` is deprecated in favor of
:class:`~factory.fuzzy.FuzzyFunction`. Its fuzzer takes no argument, so the name was
misleading. It now raises a :class:`DeprecationWarning`.


3.3.3 (2025-02-03)
------------------
Expand Down
22 changes: 18 additions & 4 deletions docs/fuzzy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ random declarations.
.. note:: Use ``import factory.fuzzy`` to load this module.


FuzzyAttribute
--------------
FuzzyFunction
-------------


.. class:: FuzzyAttribute
.. class:: FuzzyFunction

The :class:`FuzzyAttribute` uses an arbitrary callable as fuzzer.
The :class:`FuzzyFunction` uses an arbitrary callable as fuzzer.
It is expected that successive calls of that function return various
values.

Expand All @@ -31,6 +31,20 @@ FuzzyAttribute
The callable that generates random values


FuzzyAttribute
--------------


.. class:: FuzzyAttribute

.. deprecated:: 3.3.4
Use :class:`FuzzyFunction` instead. The fuzzer takes no argument, so
the name is misleading: it behaves like :class:`~factory.LazyFunction`,
not :class:`~factory.LazyAttribute`.

A deprecated alias for :class:`FuzzyFunction`.


FuzzyText
---------

Expand Down
22 changes: 19 additions & 3 deletions factory/fuzzy.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ def evaluate(self, instance, step, extra):
return self.fuzz()


class FuzzyAttribute(BaseFuzzyAttribute):
"""Similar to LazyAttribute, but yields random values.
class FuzzyFunction(BaseFuzzyAttribute):
"""Similar to LazyFunction, but yields random values.

Attributes:
function (callable): function taking no parameters and returning a
fuzzer (callable): function taking no parameters and returning a
random value.
"""

Expand All @@ -47,6 +47,22 @@ def fuzz(self):
return self.fuzzer()


class FuzzyAttribute(FuzzyFunction):
"""Deprecated alias for FuzzyFunction.

The name is misleading: the fuzzer takes no argument, so this behaves like
LazyFunction rather than LazyAttribute. Use FuzzyFunction instead.
"""

def __init__(self, fuzzer):
warnings.warn(
"FuzzyAttribute is deprecated, use FuzzyFunction instead.",
DeprecationWarning,
stacklevel=2,
)
super().__init__(fuzzer)


class FuzzyText(BaseFuzzyAttribute):
"""Random string with a given prefix.

Expand Down
19 changes: 18 additions & 1 deletion tests/test_fuzzy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,26 @@
from . import utils


class FuzzyFunctionTestCase(unittest.TestCase):
def test_simple_call(self):
d = fuzzy.FuzzyFunction(lambda: 10)

res = utils.evaluate_declaration(d)
self.assertEqual(10, res)

res = utils.evaluate_declaration(d)
self.assertEqual(10, res)


class FuzzyAttributeTestCase(unittest.TestCase):
def test_simple_call(self):
d = fuzzy.FuzzyAttribute(lambda: 10)
with warnings.catch_warnings(record=True) as w:
warnings.filterwarnings("default", category=DeprecationWarning)
d = fuzzy.FuzzyAttribute(lambda: 10)

self.assertEqual(1, len(w))
self.assertIs(DeprecationWarning, w[-1].category)
self.assertIn('FuzzyFunction', str(w[-1].message))

res = utils.evaluate_declaration(d)
self.assertEqual(10, res)
Expand Down