diff options
author | Raphaël Barrois <raphael.barrois@polyconseil.fr> | 2011-08-22 15:53:40 +0200 |
---|---|---|
committer | Raphaël Barrois <raphael.barrois@polyconseil.fr> | 2011-08-22 15:53:40 +0200 |
commit | 6983f7fcbb9bad0ea825fb3de8682f178fab5647 (patch) | |
tree | a8e24a7d63637adf3bf5541514d5c745212e054b /factory/base.py | |
parent | 0064fcff0df2c04c48e3e70723a2f523d30fb533 (diff) | |
download | factory-boy-6983f7fcbb9bad0ea825fb3de8682f178fab5647.tar factory-boy-6983f7fcbb9bad0ea825fb3de8682f178fab5647.tar.gz |
Allow inheriting from more than one factory.
Signed-off-by: Raphaël Barrois <raphael.barrois@polyconseil.fr>
Diffstat (limited to 'factory/base.py')
-rw-r--r-- | factory/base.py | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/factory/base.py b/factory/base.py index b17938e..858f20e 100644 --- a/factory/base.py +++ b/factory/base.py @@ -46,12 +46,8 @@ CLASS_ATTRIBUTE_ASSOCIATED_CLASS = '_associated_class' # Factory metaclasses def get_factory_base(bases): - parents = [b for b in bases if isinstance(b, BaseFactoryMetaClass)] - if not parents: - return None - if len(parents) > 1: - raise RuntimeError('You can only inherit from one Factory') - return parents[0] + return [b for b in bases if isinstance(b, BaseFactoryMetaClass)] + class BaseFactoryMetaClass(type): '''Factory metaclass for handling ordered declarations.''' @@ -72,19 +68,22 @@ class BaseFactoryMetaClass(type): '''Record attributes (unordered declarations) and ordered declarations for construction of an associated class instance at a later time.''' - base = get_factory_base(bases) - if not base or attrs.get('ABSTRACT_FACTORY', False): + parent_factories = get_factory_base(bases) + if not parent_factories or attrs.get('ABSTRACT_FACTORY', False): # If this isn't a subclass of Factory, don't do anything special. return super(BaseFactoryMetaClass, cls).__new__(cls, class_name, bases, attrs) - declarations = DeclarationsHolder(defaults=getattr(base, CLASS_ATTRIBUTE_DECLARATIONS, {})) - attrs = declarations.update_base(attrs) + declarations = DeclarationsHolder() + for base in parent_factories: + declarations.update_base(getattr(base, CLASS_ATTRIBUTE_DECLARATIONS, {})) + + non_factory_attrs = declarations.update_base(attrs) - attrs[CLASS_ATTRIBUTE_DECLARATIONS] = declarations + non_factory_attrs[CLASS_ATTRIBUTE_DECLARATIONS] = declarations - attrs.update(extra_attrs) + non_factory_attrs.update(extra_attrs) - return super(BaseFactoryMetaClass, cls).__new__(cls, class_name, bases, attrs) + return super(BaseFactoryMetaClass, cls).__new__(cls, class_name, bases, non_factory_attrs) class FactoryMetaClass(BaseFactoryMetaClass): '''Factory metaclass for handling class association and ordered declarations.''' @@ -99,11 +98,13 @@ class FactoryMetaClass(BaseFactoryMetaClass): '''Determine the associated class based on the factory class name. Record the associated class for construction of an associated class instance at a later time.''' - base = get_factory_base(bases) - if not base or attrs.get('ABSTRACT_FACTORY', False): + parent_factories = get_factory_base(bases) + if not parent_factories or attrs.get('ABSTRACT_FACTORY', False): # If this isn't a subclass of Factory, don't do anything special. return super(FactoryMetaClass, cls).__new__(cls, class_name, bases, attrs) + base = parent_factories[0] + inherited_associated_class = getattr(base, CLASS_ATTRIBUTE_ASSOCIATED_CLASS, None) own_associated_class = None used_auto_discovery = False |