summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--factory/containers.py23
-rw-r--r--tests/test_containers.py8
-rw-r--r--tests/test_using.py16
3 files changed, 42 insertions, 5 deletions
diff --git a/factory/containers.py b/factory/containers.py
index 4127851..497e98c 100644
--- a/factory/containers.py
+++ b/factory/containers.py
@@ -104,20 +104,35 @@ class LazyStub(object):
class DeclarationDict(dict):
"""Slightly extended dict to work with OrderedDeclaration."""
+ def is_declaration(self, name, value):
+ """Determines if a class attribute is a field value declaration.
+
+ Based on the name and value of the class attribute, return ``True`` if
+ it looks like a declaration of a default field value, ``False`` if it
+ is private (name starts with '_') or a classmethod or staticmethod.
+
+ """
+ if isinstance(value, (classmethod, staticmethod)):
+ return False
+ elif isinstance(value, declarations.OrderedDeclaration):
+ return True
+ return (not name.startswith("_"))
+
def update_with_public(self, d):
"""Updates the DeclarationDict from a class definition dict.
Takes into account all public attributes and OrderedDeclaration
- instances; ignores all attributes starting with '_'.
+ instances; ignores all class/staticmethods and private attributes
+ (starting with '_').
Returns a dict containing all remaining elements.
"""
remaining = {}
for k, v in d.iteritems():
- if k.startswith('_') and not isinstance(v, declarations.OrderedDeclaration):
- remaining[k] = v
- else:
+ if self.is_declaration(k, v):
self[k] = v
+ else:
+ remaining[k] = v
return remaining
def copy(self, extra=None):
diff --git a/tests/test_containers.py b/tests/test_containers.py
index 57c06cf..effb060 100644
--- a/tests/test_containers.py
+++ b/tests/test_containers.py
@@ -159,7 +159,13 @@ class DeclarationDictTestCase(unittest.TestCase):
def test_update_with_public(self):
d = containers.DeclarationDict()
- d.update_with_public({'one': 1, '_two': 2, 'three': 3})
+ d.update_with_public({
+ 'one': 1,
+ '_two': 2,
+ 'three': 3,
+ 'classmethod': classmethod(lambda c: 1),
+ 'staticmethod': staticmethod(lambda: 1),
+ })
self.assertEqual(set(['one', 'three']), set(d))
self.assertEqual(set([1, 3]), set(d.values()))
diff --git a/tests/test_using.py b/tests/test_using.py
index e0e59cd..d1e4262 100644
--- a/tests/test_using.py
+++ b/tests/test_using.py
@@ -280,6 +280,22 @@ class FactoryTestCase(unittest.TestCase):
test_object = TestModelFactory.create()
self.assertEqual(test_object, "This doesn't even return an instance of TestModel")
+ def testClassMethodAccessible(self):
+ class TestObjectFactory(factory.Factory):
+ @classmethod
+ def alt_create(cls, **kwargs):
+ return kwargs
+
+ self.assertEqual(TestObjectFactory.alt_create(foo=1), {"foo": 1})
+
+ def testStaticMethodAccessible(self):
+ class TestObjectFactory(factory.Factory):
+ @staticmethod
+ def alt_create(**kwargs):
+ return kwargs
+
+ self.assertEqual(TestObjectFactory.alt_create(foo=1), {"foo": 1})
+
class SubFactoryTestCase(unittest.TestCase):
def testSubFactory(self):