From fa6d60d17ddb7b70c6bc2337d901ef8cc924e67b Mon Sep 17 00:00:00 2001 From: Raphaƫl Barrois Date: Wed, 20 May 2015 23:24:45 +0200 Subject: Add Meta.rename to handle name conflicts (See #206). Define ``Meta.rename = {'attrs': 'attributes'}`` if your model expects a ``attributes`` kwarg but you can't define it since it's already reserved by the ``Factory`` class. --- docs/changelog.rst | 9 +++++++++ docs/reference.rst | 23 ++++++++++++++++++++++- factory/base.py | 8 ++++++++ tests/test_using.py | 15 +++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 8f63567..cd5d281 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,15 @@ ChangeLog ========= +.. _v2.6.0: + +2.6.0 (XXXX-XX-XX) +------------------ + +*New:* + + - Add :attr:`factory.FactoryOptions.rename` to help handle conflicting names (:issue:`206`) + .. _v2.5.2: 2.5.2 (2015-04-21) diff --git a/docs/reference.rst b/docs/reference.rst index 44f78b6..0705ca2 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -106,6 +106,28 @@ The :class:`Factory` class .. versionadded:: 2.4.0 + .. attribute:: rename + + Sometimes, a model expect a field with a name already used by one + of :class:`Factory`'s methods. + + In this case, the :attr:`rename` attributes allows to define renaming + rules: the keys of the :attr:`rename` dict are those used in the + :class:`Factory` declarations, and their values the new name: + + .. code-block:: python + + class ImageFactory(factory.Factory): + # The model expects "attributes" + form_attributes = ['thumbnail', 'black-and-white'] + + class Meta: + model = Image + rename = {'form_attributes': 'attributes'} + + .. versionadded: 2.6.0 + + .. attribute:: strategy Use this attribute to change the strategy used by a :class:`Factory`. @@ -229,7 +251,6 @@ The :class:`Factory` class .. OHAI_VIM** - .. classmethod:: _setup_next_sequence(cls) This method will compute the first value to use for the sequence counter diff --git a/factory/base.py b/factory/base.py index d48edd5..0f2af59 100644 --- a/factory/base.py +++ b/factory/base.py @@ -176,6 +176,7 @@ class FactoryOptions(object): OptionDefault('strategy', CREATE_STRATEGY, inherit=True), OptionDefault('inline_args', (), inherit=True), OptionDefault('exclude', (), inherit=True), + OptionDefault('rename', {}, inherit=True), ] def _fill_from_meta(self, meta, base_meta): @@ -412,6 +413,12 @@ class BaseFactory(object): decls.update(extra_defs or {}) return decls + @classmethod + def _rename_fields(cls, **kwargs): + for old_name, new_name in cls._meta.rename.items(): + kwargs[new_name] = kwargs.pop(old_name) + return kwargs + @classmethod def _adjust_kwargs(cls, **kwargs): """Extension point for custom kwargs adjustment.""" @@ -441,6 +448,7 @@ class BaseFactory(object): **kwargs: arguments to pass to the creation function """ model_class = cls._get_model_class() + kwargs = cls._rename_fields(**kwargs) kwargs = cls._adjust_kwargs(**kwargs) # Remove 'hidden' arguments. diff --git a/tests/test_using.py b/tests/test_using.py index b7fea81..6d75531 100644 --- a/tests/test_using.py +++ b/tests/test_using.py @@ -1076,6 +1076,21 @@ class KwargAdjustTestCase(unittest.TestCase): self.assertEqual({'x': 1, 'y': 2, 'z': 3, 'foo': 3}, obj.kwargs) self.assertEqual((), obj.args) + def test_rename(self): + class TestObject(object): + def __init__(self, attributes=None): + self.attributes = attributes + + class TestObjectFactory(factory.Factory): + class Meta: + model = TestObject + rename = {'attributes_': 'attributes'} + + attributes_ = 42 + + obj = TestObjectFactory.build() + self.assertEqual(42, obj.attributes) + class SubFactoryTestCase(unittest.TestCase): def test_sub_factory(self): -- cgit v1.2.3