summaryrefslogtreecommitdiff
path: root/factory
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@polytechnique.org>2013-04-03 01:17:26 +0200
committerRaphaël Barrois <raphael.barrois@polytechnique.org>2013-04-03 01:19:45 +0200
commit8c1784e8c1eac65f66b4a1ecc4b8b0ddd5de9327 (patch)
tree0b1d368f114de4235dc3d88e2dfc41b3403d16ef /factory
parent3aee208ee7cdf480cbc173cf3084ce2217a5944f (diff)
downloadfactory-boy-8c1784e8c1eac65f66b4a1ecc4b8b0ddd5de9327.tar
factory-boy-8c1784e8c1eac65f66b4a1ecc4b8b0ddd5de9327.tar.gz
Pylint.
Diffstat (limited to 'factory')
-rw-r--r--factory/__init__.py28
-rw-r--r--factory/base.py123
-rw-r--r--factory/compat.py10
-rw-r--r--factory/containers.py7
-rw-r--r--factory/declarations.py39
-rw-r--r--factory/helpers.py123
6 files changed, 190 insertions, 140 deletions
diff --git a/factory/__init__.py b/factory/__init__.py
index adcf9c9..beb422e 100644
--- a/factory/__init__.py
+++ b/factory/__init__.py
@@ -28,19 +28,6 @@ from .base import (
StubFactory,
DjangoModelFactory,
- build,
- create,
- stub,
- generate,
- simple_generate,
- make_factory,
-
- build_batch,
- create_batch,
- stub_batch,
- generate_batch,
- simple_generate_batch,
-
BUILD_STRATEGY,
CREATE_STRATEGY,
STUB_STRATEGY,
@@ -58,6 +45,21 @@ from .declarations import (
PostGeneration,
PostGenerationMethodCall,
RelatedFactory,
+)
+
+from .helpers import (
+ build,
+ create,
+ stub,
+ generate,
+ simple_generate,
+ make_factory,
+
+ build_batch,
+ create_batch,
+ stub_batch,
+ generate_batch,
+ simple_generate_batch,
lazy_attribute,
iterator,
diff --git a/factory/base.py b/factory/base.py
index 71c2eb1..13a0623 100644
--- a/factory/base.py
+++ b/factory/base.py
@@ -20,10 +20,6 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-import re
-import sys
-import warnings
-
from . import containers
# Strategies
@@ -68,7 +64,7 @@ class FactoryMetaClass(type):
"""Factory metaclass for handling ordered declarations."""
def __call__(cls, **kwargs):
- """Override the default Factory() syntax to call the default build strategy.
+ """Override the default Factory() syntax to call the default strategy.
Returns an instance of the associated class.
"""
@@ -80,10 +76,11 @@ class FactoryMetaClass(type):
elif cls.FACTORY_STRATEGY == STUB_STRATEGY:
return cls.stub(**kwargs)
else:
- raise UnknownStrategy('Unknown FACTORY_STRATEGY: {0}'.format(cls.FACTORY_STRATEGY))
+ raise UnknownStrategy('Unknown FACTORY_STRATEGY: {0}'.format(
+ cls.FACTORY_STRATEGY))
@classmethod
- def _discover_associated_class(cls, class_name, attrs, inherited=None):
+ def _discover_associated_class(mcs, class_name, attrs, inherited=None):
"""Try to find the class associated with this factory.
In order, the following tests will be performed:
@@ -104,8 +101,6 @@ class FactoryMetaClass(type):
AssociatedClassError: If we were unable to associate this factory
to a class.
"""
- own_associated_class = None
-
if FACTORY_CLASS_DECLARATION in attrs:
return attrs[FACTORY_CLASS_DECLARATION]
@@ -120,7 +115,7 @@ class FactoryMetaClass(type):
class_name)
@classmethod
- def _extract_declarations(cls, bases, attributes):
+ def _extract_declarations(mcs, bases, attributes):
"""Extract declarations from a class definition.
Args:
@@ -141,7 +136,8 @@ class FactoryMetaClass(type):
postgen_declarations.update_with_public(
getattr(base, CLASS_ATTRIBUTE_POSTGEN_DECLARATIONS, {}))
# Import all 'public' attributes (avoid those starting with _)
- declarations.update_with_public(getattr(base, CLASS_ATTRIBUTE_DECLARATIONS, {}))
+ declarations.update_with_public(
+ getattr(base, CLASS_ATTRIBUTE_DECLARATIONS, {}))
# Import attributes from the class definition
attributes = postgen_declarations.update_with_public(attributes)
@@ -154,7 +150,7 @@ class FactoryMetaClass(type):
return attributes
- def __new__(cls, class_name, bases, attrs, extra_attrs=None):
+ def __new__(mcs, class_name, bases, attrs, extra_attrs=None):
"""Record attributes as a pattern for later instance construction.
This is called when a new Factory subclass is defined; it will collect
@@ -174,7 +170,8 @@ class FactoryMetaClass(type):
"""
parent_factories = get_factory_bases(bases)
if not parent_factories:
- return super(FactoryMetaClass, cls).__new__(cls, class_name, bases, attrs)
+ return super(FactoryMetaClass, mcs).__new__(
+ mcs, class_name, bases, attrs)
is_abstract = attrs.pop('ABSTRACT_FACTORY', False)
extra_attrs = {}
@@ -185,7 +182,7 @@ class FactoryMetaClass(type):
inherited_associated_class = getattr(base,
CLASS_ATTRIBUTE_ASSOCIATED_CLASS, None)
- associated_class = cls._discover_associated_class(class_name, attrs,
+ associated_class = mcs._discover_associated_class(class_name, attrs,
inherited_associated_class)
# If inheriting the factory from a parent, keep a link to it.
@@ -193,22 +190,23 @@ class FactoryMetaClass(type):
if associated_class == inherited_associated_class:
attrs['_base_factory'] = base
- # The CLASS_ATTRIBUTE_ASSOCIATED_CLASS must *not* be taken into account
- # when parsing the declared attributes of the new class.
+ # The CLASS_ATTRIBUTE_ASSOCIATED_CLASS must *not* be taken into
+ # account when parsing the declared attributes of the new class.
extra_attrs = {CLASS_ATTRIBUTE_ASSOCIATED_CLASS: associated_class}
# Extract pre- and post-generation declarations
- attributes = cls._extract_declarations(parent_factories, attrs)
+ attributes = mcs._extract_declarations(parent_factories, attrs)
# Add extra args if provided.
if extra_attrs:
attributes.update(extra_attrs)
- return super(FactoryMetaClass, cls).__new__(cls, class_name, bases, attributes)
+ return super(FactoryMetaClass, mcs).__new__(
+ mcs, class_name, bases, attributes)
- def __str__(self):
- return '<%s for %s>' % (self.__name__,
- getattr(self, CLASS_ATTRIBUTE_ASSOCIATED_CLASS).__name__)
+ def __str__(cls):
+ return '<%s for %s>' % (cls.__name__,
+ getattr(cls, CLASS_ATTRIBUTE_ASSOCIATED_CLASS).__name__)
# Factory base classes
@@ -216,6 +214,7 @@ class FactoryMetaClass(type):
class BaseFactory(object):
"""Factory base support for sequences, attributes and stubs."""
+ # Backwards compatibility
UnknownStrategy = UnknownStrategy
UnsupportedStrategy = UnsupportedStrategy
@@ -231,6 +230,9 @@ class BaseFactory(object):
# class.
_base_factory = None
+ # Holds the target class, once resolved.
+ _associated_class = None
+
# List of arguments that should be passed as *args instead of **kwargs
FACTORY_ARG_PARAMETERS = ()
@@ -329,7 +331,8 @@ class BaseFactory(object):
attrs (dict): attributes to use for generating the object
"""
# Extract declarations used for post-generation
- postgen_declarations = getattr(cls, CLASS_ATTRIBUTE_POSTGEN_DECLARATIONS)
+ postgen_declarations = getattr(cls,
+ CLASS_ATTRIBUTE_POSTGEN_DECLARATIONS)
postgen_attributes = {}
for name, decl in sorted(postgen_declarations.items()):
postgen_attributes[name] = decl.extract(name, attrs)
@@ -341,7 +344,8 @@ class BaseFactory(object):
results = {}
for name, decl in sorted(postgen_declarations.items()):
extracted, extracted_kwargs = postgen_attributes[name]
- results[name] = decl.call(obj, create, extracted, **extracted_kwargs)
+ results[name] = decl.call(obj, create, extracted,
+ **extracted_kwargs)
cls._after_postgeneration(obj, create, results)
@@ -527,7 +531,7 @@ Factory = FactoryMetaClass('Factory', (BaseFactory,), {
# Backwards compatibility
-Factory.AssociatedClassError = AssociatedClassError
+Factory.AssociatedClassError = AssociatedClassError # pylint: disable=W0201
class StubFactory(Factory):
@@ -547,7 +551,7 @@ class StubFactory(Factory):
class DjangoModelFactory(Factory):
"""Factory for Django models.
- This makes sure that the 'sequence' field of created objects is an unused id.
+ This makes sure that the 'sequence' field of created objects is a new id.
Possible improvement: define a new 'attribute' type, AutoField, which would
handle those for non-numerical primary keys.
@@ -559,7 +563,7 @@ class DjangoModelFactory(Factory):
@classmethod
def _get_manager(cls, target_class):
try:
- return target_class._default_manager
+ return target_class._default_manager # pylint: disable=W0212
except AttributeError:
return target_class.objects
@@ -567,7 +571,8 @@ class DjangoModelFactory(Factory):
def _setup_next_sequence(cls):
"""Compute the next available PK, based on the 'pk' database field."""
- manager = cls._get_manager(cls._associated_class)
+ model = cls._associated_class # pylint: disable=E1101
+ manager = cls._get_manager(model)
try:
return 1 + manager.values_list('pk', flat=True
@@ -590,7 +595,7 @@ class DjangoModelFactory(Factory):
key_fields[field] = kwargs.pop(field)
key_fields['defaults'] = kwargs
- obj, created = manager.get_or_create(*args, **key_fields)
+ obj, _created = manager.get_or_create(*args, **key_fields)
return obj
@classmethod
@@ -610,68 +615,6 @@ class MogoFactory(Factory):
return target_class.new(*args, **kwargs)
-def make_factory(klass, **kwargs):
- """Create a new, simple factory for the given class."""
- factory_name = '%sFactory' % klass.__name__
- kwargs[FACTORY_CLASS_DECLARATION] = klass
- base_class = kwargs.pop('FACTORY_CLASS', Factory)
-
- factory_class = type(Factory).__new__(type(Factory), factory_name, (base_class,), kwargs)
- factory_class.__name__ = '%sFactory' % klass.__name__
- factory_class.__doc__ = 'Auto-generated factory for class %s' % klass
- return factory_class
-
-
-def build(klass, **kwargs):
- """Create a factory for the given class, and build an instance."""
- return make_factory(klass, **kwargs).build()
-
-
-def build_batch(klass, size, **kwargs):
- """Create a factory for the given class, and build a batch of instances."""
- return make_factory(klass, **kwargs).build_batch(size)
-
-
-def create(klass, **kwargs):
- """Create a factory for the given class, and create an instance."""
- return make_factory(klass, **kwargs).create()
-
-
-def create_batch(klass, size, **kwargs):
- """Create a factory for the given class, and create a batch of instances."""
- return make_factory(klass, **kwargs).create_batch(size)
-
-
-def stub(klass, **kwargs):
- """Create a factory for the given class, and stub an instance."""
- return make_factory(klass, **kwargs).stub()
-
-
-def stub_batch(klass, size, **kwargs):
- """Create a factory for the given class, and stub a batch of instances."""
- return make_factory(klass, **kwargs).stub_batch(size)
-
-
-def generate(klass, strategy, **kwargs):
- """Create a factory for the given class, and generate an instance."""
- return make_factory(klass, **kwargs).generate(strategy)
-
-
-def generate_batch(klass, strategy, size, **kwargs):
- """Create a factory for the given class, and generate instances."""
- return make_factory(klass, **kwargs).generate_batch(strategy, size)
-
-
-def simple_generate(klass, create, **kwargs):
- """Create a factory for the given class, and simple_generate an instance."""
- return make_factory(klass, **kwargs).simple_generate(create)
-
-
-def simple_generate_batch(klass, create, size, **kwargs):
- """Create a factory for the given class, and simple_generate instances."""
- return make_factory(klass, **kwargs).simple_generate_batch(create, size)
-
-
def use_strategy(new_strategy):
"""Force the use of a different strategy.
diff --git a/factory/compat.py b/factory/compat.py
index a924de0..84f31b7 100644
--- a/factory/compat.py
+++ b/factory/compat.py
@@ -25,9 +25,11 @@
import sys
-is_python2 = (sys.version_info[0] == 2)
+PY2 = (sys.version_info[0] == 2)
-if is_python2:
- string_types = (str, unicode)
+if PY2:
+ def is_string(obj):
+ return isinstance(obj, (str, unicode))
else:
- string_types = (str,)
+ def is_string(obj):
+ return isinstance(obj, str)
diff --git a/factory/containers.py b/factory/containers.py
index dc3a457..e02f9f9 100644
--- a/factory/containers.py
+++ b/factory/containers.py
@@ -228,9 +228,12 @@ class AttributeBuilder(object):
self._containers = extra.pop('__containers', ())
self._attrs = factory.declarations(extra)
- attrs_with_subfields = [k for k, v in self._attrs.items() if self.has_subfields(v)]
+ attrs_with_subfields = [
+ k for k, v in self._attrs.items()
+ if self.has_subfields(v)]
- self._subfields = utils.multi_extract_dict(attrs_with_subfields, self._attrs)
+ self._subfields = utils.multi_extract_dict(
+ attrs_with_subfields, self._attrs)
def has_subfields(self, value):
return isinstance(value, declarations.SubFactory)
diff --git a/factory/declarations.py b/factory/declarations.py
index 15d8d5b..3d76960 100644
--- a/factory/declarations.py
+++ b/factory/declarations.py
@@ -21,9 +21,7 @@
# THE SOFTWARE.
-import collections
import itertools
-import warnings
from . import compat
from . import utils
@@ -179,7 +177,7 @@ class Sequence(OrderedDeclaration):
type (function): A function converting an integer into the expected kind
of counter for the 'function' attribute.
"""
- def __init__(self, function, type=int):
+ def __init__(self, function, type=int): # pylint: disable=W0622
super(Sequence, self).__init__()
self.function = function
self.type = type
@@ -318,7 +316,7 @@ class SubFactory(ParameteredAttribute):
self.factory_module = self.factory_name = ''
else:
# Must be a string
- if not isinstance(factory, compat.string_types) or '.' not in factory:
+ if not (compat.is_string(factory) and '.' in factory):
raise ValueError(
"The argument of a SubFactory must be either a class "
"or the fully qualified path to a Factory class; got "
@@ -330,7 +328,8 @@ class SubFactory(ParameteredAttribute):
"""Retrieve the wrapped factory.Factory subclass."""
if self.factory is None:
# Must be a module path
- self.factory = utils.import_object(self.factory_module, self.factory_name)
+ self.factory = utils.import_object(
+ self.factory_module, self.factory_name)
return self.factory
def generate(self, create, params):
@@ -390,10 +389,6 @@ class PostGeneration(PostGenerationDeclaration):
return self.function(obj, create, extracted, **kwargs)
-def post_generation(fun):
- return PostGeneration(fun)
-
-
class RelatedFactory(PostGenerationDeclaration):
"""Calls a factory once the object has been generated.
@@ -414,7 +409,7 @@ class RelatedFactory(PostGenerationDeclaration):
self.factory_module = self.factory_name = ''
else:
# Must be a string
- if not isinstance(factory, compat.string_types) or '.' not in factory:
+ if not (compat.is_string(factory) and '.' in factory):
raise ValueError(
"The argument of a SubFactory must be either a class "
"or the fully qualified path to a Factory class; got "
@@ -426,7 +421,8 @@ class RelatedFactory(PostGenerationDeclaration):
"""Retrieve the wrapped factory.Factory subclass."""
if self.factory is None:
# Must be a module path
- self.factory = utils.import_object(self.factory_module, self.factory_name)
+ self.factory = utils.import_object(
+ self.factory_module, self.factory_name)
return self.factory
def call(self, obj, create, extracted=None, **kwargs):
@@ -450,7 +446,7 @@ class PostGenerationMethodCall(PostGenerationDeclaration):
Example:
class UserFactory(factory.Factory):
...
- password = factory.PostGenerationMethodCall('set_password', password='')
+ password = factory.PostGenerationMethodCall('set_pass', password='')
"""
def __init__(self, method_name, *args, **kwargs):
super(PostGenerationMethodCall, self).__init__()
@@ -472,22 +468,3 @@ class PostGenerationMethodCall(PostGenerationDeclaration):
passed_kwargs.update(kwargs)
method = getattr(obj, self.method_name)
method(*passed_args, **passed_kwargs)
-
-
-# Decorators... in case lambdas don't cut it
-
-def lazy_attribute(func):
- return LazyAttribute(func)
-
-def iterator(func):
- """Turn a generator function into an iterator attribute."""
- return Iterator(func())
-
-def sequence(func):
- return Sequence(func)
-
-def lazy_attribute_sequence(func):
- return LazyAttributeSequence(func)
-
-def container_attribute(func):
- return ContainerAttribute(func, strict=False)
diff --git a/factory/helpers.py b/factory/helpers.py
new file mode 100644
index 0000000..8f0d161
--- /dev/null
+++ b/factory/helpers.py
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2010 Mark Sandstrom
+# Copyright (c) 2011-2013 Raphaël Barrois
+#
+# 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
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+
+"""Simple wrappers around Factory class definition."""
+
+
+from . import base
+from . import declarations
+
+
+def make_factory(klass, **kwargs):
+ """Create a new, simple factory for the given class."""
+ factory_name = '%sFactory' % klass.__name__
+ kwargs[base.FACTORY_CLASS_DECLARATION] = klass
+ base_class = kwargs.pop('FACTORY_CLASS', base.Factory)
+
+ factory_class = type(base.Factory).__new__(
+ type(base.Factory), factory_name, (base_class,), kwargs)
+ factory_class.__name__ = '%sFactory' % klass.__name__
+ factory_class.__doc__ = 'Auto-generated factory for class %s' % klass
+ return factory_class
+
+
+def build(klass, **kwargs):
+ """Create a factory for the given class, and build an instance."""
+ return make_factory(klass, **kwargs).build()
+
+
+def build_batch(klass, size, **kwargs):
+ """Create a factory for the given class, and build a batch of instances."""
+ return make_factory(klass, **kwargs).build_batch(size)
+
+
+def create(klass, **kwargs):
+ """Create a factory for the given class, and create an instance."""
+ return make_factory(klass, **kwargs).create()
+
+
+def create_batch(klass, size, **kwargs):
+ """Create a factory for the given class, and create a batch of instances."""
+ return make_factory(klass, **kwargs).create_batch(size)
+
+
+def stub(klass, **kwargs):
+ """Create a factory for the given class, and stub an instance."""
+ return make_factory(klass, **kwargs).stub()
+
+
+def stub_batch(klass, size, **kwargs):
+ """Create a factory for the given class, and stub a batch of instances."""
+ return make_factory(klass, **kwargs).stub_batch(size)
+
+
+def generate(klass, strategy, **kwargs):
+ """Create a factory for the given class, and generate an instance."""
+ return make_factory(klass, **kwargs).generate(strategy)
+
+
+def generate_batch(klass, strategy, size, **kwargs):
+ """Create a factory for the given class, and generate instances."""
+ return make_factory(klass, **kwargs).generate_batch(strategy, size)
+
+
+# We're reusing 'create' as a keyword.
+# pylint: disable=W0621
+
+
+def simple_generate(klass, create, **kwargs):
+ """Create a factory for the given class, and simple_generate an instance."""
+ return make_factory(klass, **kwargs).simple_generate(create)
+
+
+def simple_generate_batch(klass, create, size, **kwargs):
+ """Create a factory for the given class, and simple_generate instances."""
+ return make_factory(klass, **kwargs).simple_generate_batch(create, size)
+
+
+# pylint: enable=W0621
+
+
+def lazy_attribute(func):
+ return declarations.LazyAttribute(func)
+
+
+def iterator(func):
+ """Turn a generator function into an iterator attribute."""
+ return declarations.Iterator(func())
+
+
+def sequence(func):
+ return declarations.Sequence(func)
+
+
+def lazy_attribute_sequence(func):
+ return declarations.LazyAttributeSequence(func)
+
+
+def container_attribute(func):
+ return declarations.ContainerAttribute(func, strict=False)
+
+
+def post_generation(fun):
+ return declarations.PostGeneration(fun)