Skip to content

Commit

Permalink
Fixes circular dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
olegpidsadnyi committed Jun 20, 2015
1 parent 576ecaa commit f74d6de
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Changelog
=========

1.1.2
-----

- circular dependency determination is fixed for the RelatedFactory attributes (olegpidsadnyi)


1.1.1
-----

Expand Down
2 changes: 1 addition & 1 deletion pytest_factoryboy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""pytest-factoryboy public API."""
from .fixture import register, LazyFixture

__version__ = '1.1.1'
__version__ = '1.1.2'


__all__ = [
Expand Down
16 changes: 13 additions & 3 deletions pytest_factoryboy/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,16 @@ def register(factory_class, _name=None, _postgen_dependencies=None, **kwargs):

if isinstance(value, (factory.SubFactory, factory.RelatedFactory)):
subfactory_class = value.get_factory()
subfactory_deps = get_deps(subfactory_class, factory_class)
make_fixture(
name=attr_name,
module=module,
func=subfactory_fixture,
args=get_deps(subfactory_class, factory_class),
args=subfactory_deps,
factory_class=subfactory_class,
)
if isinstance(value, factory.RelatedFactory):
deps.extend(get_deps(subfactory_class, factory_class))
deps.extend(subfactory_deps)
else:
make_fixture(
name=attr_name,
Expand Down Expand Up @@ -114,10 +115,19 @@ def get_deps(factory_class, parent_factory_class=None, model_name=None):
"""
model_name = get_model_name(factory_class) if model_name is None else model_name
parent_model_name = get_model_name(parent_factory_class) if parent_factory_class is not None else None

def is_dep(value):
if isinstance(value, factory.RelatedFactory):
return False
if isinstance(value, factory.SubFactory) and get_model_name(value.get_factory()) == parent_model_name:
return False

return True

return [
SEPARATOR.join((model_name, attr))
for attr, value in factory_class.declarations(factory_class._meta.postgen_declarations).items()
if attr != parent_model_name and not isinstance(value, factory.RelatedFactory)
if is_dep(value)
]


Expand Down
55 changes: 55 additions & 0 deletions tests/test_circular.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""Test circular definitions."""

import factory

from pytest_factoryboy import register


class Book(object):

"""Book model."""

def __init__(self, name=None, price=None, author=None):
self.editions = []
self.name = name
self.price = price
self.author = author
self.author.books.append(self)


class Author(object):

"""Author model."""

def __init__(self, name):
self.books = []
self.name = name
self.user = None


class AuthorFactory(factory.Factory):

class Meta:
model = Author

name = "Charles Dickens"

book = factory.RelatedFactory('tests.test_circular.BookFactory', 'author')


class BookFactory(factory.Factory):

class Meta:
model = Book

name = "Alice in Wonderland"
price = factory.LazyAttribute(lambda f: 3.99)
author = factory.SubFactory(AuthorFactory)


register(AuthorFactory)
register(BookFactory)


def test_circular(author):
assert author.books

0 comments on commit f74d6de

Please sign in to comment.