From 6efa57cf38f945c55214a94e0e7c12cc7eff474f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Barrois?= Date: Thu, 16 Aug 2012 20:28:21 +0200 Subject: Refactor building_function/creation_function handling. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rely on inheritance instead of handwritten set_creation_function and such. Signed-off-by: Raphaƫl Barrois --- factory/base.py | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 5 deletions(-) (limited to 'factory/base.py') diff --git a/factory/base.py b/factory/base.py index 8ff6151..159a50c 100644 --- a/factory/base.py +++ b/factory/base.py @@ -316,6 +316,37 @@ class BaseFactory(object): """ return getattr(cls, CLASS_ATTRIBUTE_DECLARATIONS).copy(extra_defs) + @classmethod + def _build(cls, target_class, *args, **kwargs): + """Actually build an instance of the target_class. + + Customization point, will be called once the full set of args and kwargs + has been computed. + + Args: + target_class (type): the class for which an instance should be + built + args (tuple): arguments to use when building the class + kwargs (dict): keyword arguments to use when building the class + """ + + return target_class(*args, **kwargs) + + @classmethod + def _create(cls, target_class, *args, **kwargs): + """Actually create an instance of the target_class. + + Customization point, will be called once the full set of args and kwargs + has been computed. + + Args: + target_class (type): the class for which an instance should be + created + args (tuple): arguments to use when creating the class + kwargs (dict): keyword arguments to use when creating the class + """ + return target_class(*args, **kwargs) + @classmethod def build(cls, **kwargs): """Build an instance of the associated class, with overriden attrs.""" @@ -462,7 +493,7 @@ class Factory(BaseFactory): # Customizing 'create' strategy, using a tuple to keep the creation function # from turning it into an instance method. - _creation_function = (DJANGO_CREATION,) + _creation_function = (None,) @classmethod def set_creation_function(cls, creation_function): @@ -485,11 +516,22 @@ class Factory(BaseFactory): an instance will be created, and keyword arguments for the value of the fields of the instance. """ - return cls._creation_function[0] + creation_function = cls._creation_function[0] + if creation_function: + return creation_function + elif cls._create.__func__ == Factory._create.__func__: + # Backwards compatibility. + # Default creation_function and default _create() behavior. + # The best "Vanilla" _create detection algorithm I found is relying + # on actual method implementation (otherwise, make_factory isn't + # detected as 'default'). + return DJANGO_CREATION + else: + return creation_function # Customizing 'build' strategy, using a tuple to keep the creation function # from turning it into an instance method. - _building_function = (NAIVE_BUILD,) + _building_function = (None,) @classmethod def set_building_function(cls, building_function): @@ -522,10 +564,19 @@ class Factory(BaseFactory): create: bool, whether to create or to build the object **kwargs: arguments to pass to the creation function """ + target_class = getattr(cls, CLASS_ATTRIBUTE_ASSOCIATED_CLASS) if create: - return cls.get_creation_function()(getattr(cls, CLASS_ATTRIBUTE_ASSOCIATED_CLASS), **kwargs) + # Backwards compatibility + creation_function = cls.get_creation_function() + if creation_function: + return creation_function(target_class, **kwargs) + return cls._create(target_class, **kwargs) else: - return cls.get_building_function()(getattr(cls, CLASS_ATTRIBUTE_ASSOCIATED_CLASS), **kwargs) + # Backwards compatibility + building_function = cls.get_building_function() + if building_function: + return building_function(target_class, **kwargs) + return cls._build(target_class, **kwargs) @classmethod def _generate(cls, create, attrs): @@ -581,6 +632,10 @@ class DjangoModelFactory(Factory): except IndexError: return 1 + def _create(cls, target_class, *args, **kwargs): + """Create an instance of the model, and save it to the database.""" + return target_class._default_manager.create(*args, **kwargs) + def make_factory(klass, **kwargs): """Create a new, simple factory for the given class.""" -- cgit v1.2.3