Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with Maybe / Trait when defined in Params #126

Open
MRigal opened this issue Jun 24, 2021 · 3 comments
Open

Problems with Maybe / Trait when defined in Params #126

MRigal opened this issue Jun 24, 2021 · 3 comments

Comments

@MRigal
Copy link

MRigal commented Jun 24, 2021

Especially with FactoryBoy 3.2. See failing tests in #125

@MRigal MRigal changed the title Various problems with Maybe and Trait Problems with Maybe / Trait when defined in Params Jun 25, 2021
@elgin9507
Copy link

I'm still facing this issue:

AttributeError: 'Maybe' object has no attribute 'call'


request = <SubRequest 'timesheet' for <Function test_can_include_date>>

    def deferred(request):
>       declaration.call(instance, step, context)
E       AttributeError: 'Maybe' object has no attribute 'call'

../.venv/lib/python3.9/site-packages/pytest_factoryboy/fixture.py:294: AttributeError

Debugging info:

(Pdb) declaration
Maybe(<SelfAttribute('has_entries', default=False)>, yes=<factory.declarations.RelatedFactoryList object at 0x7ffb03b409d0>, no=<factory.declarations.Skip object at 0x7ffb23dcc160>)
(Pdb) type(step)
<class 'factory.builder.BuildStep'>
(Pdb) context
PostGenerationContext(value_provided=True, value=Maybe(<SelfAttribute('has_entries', default=False)>, yes=<factory.declarations.RelatedFactoryList object at 0x7ffb03b409d0>, no=<factory.declarations.Skip object at 0x7ffb23dcc160>), extra={})

Versions in my environment:

factory-boy==3.2.0
pytest==6.2.5
pytest-django==4.4.0
pytest-factoryboy==2.1.0

@satodaiki
Copy link

I also encountered the same event.

The factory I defined is the one that contains the RelatedFactory in the Trait.

as follows:

import factory

class UserFactory(factory.Factory):
    class Meta:
        model = User

    id = 1

class BookFactory(factory.Factory):
    class Meta:
        model = Book

    class Params:
        user_r = factory.Trait(
            users=factory.RelatedFactoryList("factories.UserFactory"),
            factory_related_name="id",
            size=10,
        )

    name = "book name"

I am not sure about the details of the implementation, but it worked locally by modifying the conditional expression for the decl object in the following location.

if isinstance(decl, factory.RelatedFactory):

if isinstance(decl, (factory.RelatedFactory, factory.Maybe)):

If the corrections above are sufficient to address the issue, then please fix it!

@skarzi
Copy link
Contributor

skarzi commented Aug 7, 2022

It's really hard to properly handle Maybe (and also Trait because under the hood it uses as_declarations to override affected fields with Maybe - reference).
To properly generate fixtures for Maybe we need to somehow generate a proper dependencies chain, which is really hard, because Maybe.decider can be computed from anything using some declaration, however, the most commonly used are probably the following ones:

  • SimpleParameter (in the case of Trait)
  • SelfAttribute
  • LazyAttribute

Maybes can be also nested, which makes implementation even more complicated.

If you have any idea how to add support for Maybe and/or Params to our code, please share it here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants