question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can't pass size to RelatedFactoryList from parent factory's Params

See original GitHub issue

Description

I can’t seem to find a way to pass the size kwarg from a parent factory’s params through to a RelatedFactoryList. I’ve tried every permutation of LazyAttribute to SelfAttribute to lambdas.

Model / Factory code
class BarFactory(factory.DjangoModelFactory)
    class Meta:
        model = Bar

class FooFactory(factory.DjangoModelFactory)
    class Meta:
        model = Foo

    class Params:
        size = 2

    bars = factory.RelatedFactoryList(BarFactory, size=factory.SelfAttribute('..size'))
The issue
FooFactory()
# ->
  File "/usr/local/lib/python3.7/site-packages/factory/base.py", line 46, in __call__
    return cls.create(**kwargs)
  File "/usr/local/lib/python3.7/site-packages/factory/base.py", line 564, in create
    return cls._generate(enums.CREATE_STRATEGY, kwargs)
  File "/usr/local/lib/python3.7/site-packages/factory/django.py", line 141, in _generate
    return super(DjangoModelFactory, cls)._generate(strategy, params)
  File "/usr/local/lib/python3.7/site-packages/factory/base.py", line 501, in _generate
    return step.build()
  File "/usr/local/lib/python3.7/site-packages/factory/builder.py", line 272, in build
    step.resolve(pre)
  File "/usr/local/lib/python3.7/site-packages/factory/builder.py", line 221, in resolve
    self.attributes[field_name] = getattr(self.stub, field_name)
  File "/usr/local/lib/python3.7/site-packages/factory/builder.py", line 375, in __getattr__
    extra=context,
  File "/usr/local/lib/python3.7/site-packages/factory/declarations.py", line 321, in evaluate
    return self.generate(step, defaults)
  File "/usr/local/lib/python3.7/site-packages/factory/declarations.py", line 411, in generate
    return step.recurse(subfactory, params, force_sequence=force_sequence)
  File "/usr/local/lib/python3.7/site-packages/factory/builder.py", line 233, in recurse
    return builder.build(parent_step=self, force_sequence=force_sequence)
  File "/usr/local/lib/python3.7/site-packages/factory/builder.py", line 299, in build
    context=postgen_context,
  File "/usr/local/lib/python3.7/site-packages/factory/declarations.py", line 694, in call
    else self.size())]
TypeError: 'SelfAttribute' object is not callable

Notes

If there is a different strategy for passing the size of a RelatedFactoryList from it’s parent Factory (i.e. being able to specify size of the list when instantiating the parent factory via a kwarg) I’d be happy to know of an alternative approach.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:3
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
ibushongcommented, Sep 19, 2020

I had the same issue. Here was my quick solution (I know this would cause issues in some cases, but it worked for my usage)

class RelatedFactoryVariableList(RelatedFactoryList):
    """allows overriding ``size`` during factory usage, e.g. ParentFactory(list_factory__size=4)"""
    def call(self, instance, step, context):
        size = context.extra.get('size', self.size)
        assert isinstance(size, int)
        return [super(RelatedFactoryList, self).call(instance, step, context) for i in range(size)]

So for OP’s example, you would use it like FooFactory(bars__size=4)

1reaction
timorthicommented, Aug 21, 2020

I also ran into this issue with RelatedFactoryList.

I got around this by using the post_generation hook to create my related factory list manually. From what I can tell, there is no support for the size param to be a LazyAttribute or SelfAttribute. There’s an inactive but relevant PR about this at #727.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reference — Factory Boy stable documentation
If unset, it will be inherited from parent Factory subclasses. ... Provides a list of size instances from the Factory , through the...
Read more >
Inherit Params from parent factory with factory_boy
I'm working toward the same goal. I want to DRY up my factories since I'm using polymorphic models. the bad news is the...
Read more >
Factory Boy Documentation - Read the Docs
When a Factory includes related fields (SubFactory, RelatedFactory), the parent's strategy will be pushed onto related factories.
Read more >
Improve your Django tests with fakes and factories - HackSoft
I literally can't think of a factory that we've written that ... You can always pass start_date and end_date to the Factory if...
Read more >
Factory injection, combining pytest with factory_boy
@pytest.fixture def you(your_father): """You can't be created without ... Factory): class Meta: model = Book # Parent object is created at ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found