diff options
-rw-r--r-- | factory/__init__.py | 6 | ||||
-rw-r--r-- | factory/base.py | 68 | ||||
-rw-r--r-- | factory/containers.py | 22 | ||||
-rw-r--r-- | factory/declarations.py | 24 |
4 files changed, 60 insertions, 60 deletions
diff --git a/factory/__init__.py b/factory/__init__.py index 650f572..bf0fca2 100644 --- a/factory/__init__.py +++ b/factory/__init__.py @@ -1,15 +1,15 @@ # Copyright (c) 2010 Mark Sandstrom -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/factory/base.py b/factory/base.py index 5f712a2..d7c40c1 100644 --- a/factory/base.py +++ b/factory/base.py @@ -1,15 +1,15 @@ # Copyright (c) 2010 Mark Sandstrom -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -33,7 +33,7 @@ STUB_STRATEGY = 'stub' # Creation functions. Use Factory.set_creation_function() to set a creation function appropriate for your ORM. DJANGO_CREATION = lambda class_to_create, **kwargs: class_to_create.objects.create(**kwargs) - + # Special declarations FACTORY_CLASS_DECLARATION = 'FACTORY_FOR' @@ -56,10 +56,10 @@ def get_factory_base(bases): class BaseFactoryMetaClass(type): '''Factory metaclass for handling ordered declarations.''' - + def __call__(cls, **kwargs): '''Create an associated class instance using the default build strategy. Never create a Factory instance.''' - + if cls.default_strategy == BUILD_STRATEGY: return cls.build(**kwargs) elif cls.default_strategy == CREATE_STRATEGY: @@ -68,16 +68,16 @@ class BaseFactoryMetaClass(type): return cls.stub(**kwargs) else: raise BaseFactory.UnknownStrategy('Unknown default_strategy: {0}'.format(cls.default_strategy)) - + def __new__(cls, class_name, bases, dict, extra_dict={}): '''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: # If this isn't a subclass of Factory, don't do anything special. return super(BaseFactoryMetaClass, cls).__new__(cls, class_name, bases, dict) - + ordered_declarations = getattr(base, CLASS_ATTRIBUTE_ORDERED_DECLARATIONS, []) unordered_declarations = getattr(base, CLASS_ATTRIBUTE_UNORDERED_DECLARATIONS, []) @@ -95,7 +95,7 @@ class BaseFactoryMetaClass(type): dict[CLASS_ATTRIBUTE_ORDERED_DECLARATIONS] = ordered_declarations dict[CLASS_ATTRIBUTE_UNORDERED_DECLARATIONS] = unordered_declarations - + for name, value in extra_dict.iteritems(): dict[name] = value @@ -103,26 +103,26 @@ class BaseFactoryMetaClass(type): class FactoryMetaClass(BaseFactoryMetaClass): '''Factory metaclass for handling class association and ordered declarations.''' - + ERROR_MESSAGE = '''Could not determine what class this factory is for. Use the {0} attribute to specify a class.''' ERROR_MESSAGE_AUTODISCOVERY = ERROR_MESSAGE + ''' Also, autodiscovery failed using the name '{1}' based on the Factory name '{2}' in {3}.''' - + def __new__(cls, class_name, bases, dict): '''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: # If this isn't a subclass of Factory, don't do anything special. return super(FactoryMetaClass, cls).__new__(cls, class_name, bases, dict) - + inherited_associated_class = getattr(base, CLASS_ATTRIBUTE_ASSOCIATED_CLASS, None) own_associated_class = None used_auto_discovery = False - + if FACTORY_CLASS_DECLARATION in dict: own_associated_class = dict[FACTORY_CLASS_DECLARATION] del dict[FACTORY_CLASS_DECLARATION] @@ -136,41 +136,41 @@ class FactoryMetaClass(BaseFactoryMetaClass): own_associated_class = getattr(factory_module, associated_class_name) except AttributeError: pass - + if own_associated_class != None and inherited_associated_class != None and own_associated_class != inherited_associated_class: format = 'These factories are for conflicting classes: {0} and {1}' raise Factory.AssociatedClassError(format.format(inherited_associated_class, own_associated_class)) elif inherited_associated_class != None: own_associated_class = inherited_associated_class - + if not own_associated_class and used_auto_discovery: format_args = FACTORY_CLASS_DECLARATION, associated_class_name, class_name, factory_module raise Factory.AssociatedClassError(FactoryMetaClass.ERROR_MESSAGE_AUTODISCOVERY.format(*format_args)) elif not own_associated_class: raise Factory.AssociatedClassError(FactoryMetaClass.ERROR_MESSAGE.format(FACTORY_CLASS_DECLARATION)) - + extra_dict = {CLASS_ATTRIBUTE_ASSOCIATED_CLASS: own_associated_class} - return super(FactoryMetaClass, cls).__new__(cls, class_name, bases, dict, extra_dict=extra_dict) + return super(FactoryMetaClass, cls).__new__(cls, class_name, bases, dict, extra_dict=extra_dict) # Factory base classes class BaseFactory(object): '''Factory base support for sequences, attributes and stubs.''' - + class UnknownStrategy(RuntimeError): pass class UnsupportedStrategy(RuntimeError): pass - + def __new__(cls, *args, **kwargs): raise RuntimeError('You cannot instantiate BaseFactory') - + _next_sequence = 0 - + @classmethod def _generate_next_sequence(cls): next_sequence = cls._next_sequence cls._next_sequence += 1 return next_sequence - + @classmethod def attributes(cls, **kwargs): attributes = {} @@ -195,15 +195,15 @@ class BaseFactory(object): attributes[name] = kwargs[name] return attributes - + @classmethod def build(cls, **kwargs): raise cls.UnsupportedStrategy() - + @classmethod def create(cls, **kwargs): raise cls.UnsupportedStrategy() - + @classmethod def stub(cls, **kwargs): stub_object = StubObject() @@ -218,15 +218,15 @@ class StubFactory(BaseFactory): class Factory(BaseFactory): '''Factory base with build and create support. - + This class has the ability to support multiple ORMs by using custom creation functions.''' - + __metaclass__ = FactoryMetaClass - + default_strategy = CREATE_STRATEGY - + class AssociatedClassError(RuntimeError): pass - + _creation_function = (DJANGO_CREATION,) # Using a tuple to keep the creation function from turning into an instance method @classmethod def set_creation_function(cls, creation_function): @@ -234,11 +234,11 @@ class Factory(BaseFactory): @classmethod def get_creation_function(cls): return cls._creation_function[0] - + @classmethod def build(cls, **kwargs): return getattr(cls, CLASS_ATTRIBUTE_ASSOCIATED_CLASS)(**cls.attributes(**kwargs)) - + @classmethod def create(cls, **kwargs): return cls.get_creation_function()(getattr(cls, CLASS_ATTRIBUTE_ASSOCIATED_CLASS), **cls.attributes(**kwargs)) diff --git a/factory/containers.py b/factory/containers.py index 08f0450..023055c 100644 --- a/factory/containers.py +++ b/factory/containers.py @@ -1,15 +1,15 @@ # Copyright (c) 2010 Mark Sandstrom -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,28 +20,28 @@ class ObjectParamsWrapper(object): '''A generic container that allows for getting but not setting of attributes. - + Attributes are set at initialization time.''' - + initialized = False - + def __init__(self, dict): self.dict = dict self.initialized = True - + def __setattr__(self, name, value): if not self.initialized: return super(ObjectParamsWrapper, self).__setattr__(name, value) else: raise AttributeError('Setting of object attributes is not allowed') - + def __getattr__(self, name): try: return self.dict[name] except KeyError: raise AttributeError("The param '{0}' does not exist. Perhaps your declarations are out of order?".format(name)) - + class StubObject(object): '''A generic container.''' - - pass
\ No newline at end of file + + pass diff --git a/factory/declarations.py b/factory/declarations.py index 37c8cbd..cf54f07 100644 --- a/factory/declarations.py +++ b/factory/declarations.py @@ -1,15 +1,15 @@ # Copyright (c) 2010 Mark Sandstrom -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,34 +20,34 @@ class OrderedDeclaration(object): '''A factory declaration. - + Ordered declarations keep track of the order in which they're defined so that later declarations can refer to attributes created by earlier declarations when the declarations are evaluated.''' _next_order = 0 - + def __init__(self): self.order = self.next_order() - + @classmethod def next_order(cls): next_order = cls._next_order cls._next_order += 1 return next_order - + def evaluate(self, factory, attributes): '''Evaluate this declaration. - + Args: factory: The factory this declaration was defined in. attributes: The attributes created by the unordered and ordered declarations up to this point.''' - + raise NotImplementedError('This is an abstract method') class LazyAttribute(OrderedDeclaration): def __init__(self, function): super(LazyAttribute, self).__init__() self.function = function - + def evaluate(self, factory, attributes): return self.function(attributes) @@ -56,7 +56,7 @@ class Sequence(OrderedDeclaration): super(Sequence, self).__init__() self.function = function self.type = type - + def evaluate(self, factory, attributes): return self.function(self.type(factory.sequence)) @@ -73,4 +73,4 @@ def sequence(func): return Sequence(func) def lazy_attribute_sequence(func): - return LazyAttributeSequence(func)
\ No newline at end of file + return LazyAttributeSequence(func) |