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

TypeError: can only concatenate str (not "PostGenerationMethodCall") to str #87

Closed
toshism opened this issue Oct 30, 2019 · 0 comments · Fixed by #103
Closed

TypeError: can only concatenate str (not "PostGenerationMethodCall") to str #87

toshism opened this issue Oct 30, 2019 · 0 comments · Fixed by #103

Comments

@toshism
Copy link

toshism commented Oct 30, 2019

When using factory.PostGenerationMethodCall on a factory I get the type error in the title.

The factory I'm working with is a django user model. Simple example:

class UserFactory(factory.django.DjangoModelFactory):
    email = factory.Sequence(lambda n: "user-{0}@example.com".format(n))
    password = factory.PostGenerationMethodCall("set_password", ["password"])
    first_name = fuzzy.FuzzyText(length=20)
    last_name = fuzzy.FuzzyText(length=20)

    class Meta:
        model = "users.User"
        django_get_or_create = ("email",)

register(UserFactory)

Attempting to use that factory as a fixture will throw:

env/lib/python3.7/site-packages/pytest_factoryboy/plugin.py:83: in evaluate
    self.execute(request, function, deferred)
env/lib/python3.7/site-packages/pytest_factoryboy/plugin.py:65: in execute
    self.results[model][attr] = function(request)
env/lib/python3.7/site-packages/pytest_factoryboy/fixture.py:273: in deferred
    declaration.call(instance, step, context)
env/lib/python3.7/site-packages/factory/declarations.py:743: in call
    return method(*args, **kwargs)
env/lib/python3.7/site-packages/django/contrib/auth/base_user.py:98: in set_password
    self.password = make_password(raw_password)
env/lib/python3.7/site-packages/django/contrib/auth/hashers.py:78: in make_password
    return hasher.encode(password, salt)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <django.contrib.auth.hashers.MD5PasswordHasher object at 0x7f1fa3759cd0>, password = <factory.declarations.PostGenerationMethodCall object at 0x7f1fa47ff390>, salt = 'XXXXXXXXX'

    def encode(self, password, salt):
        assert password is not None
        assert salt and '$' not in salt
>       hash = hashlib.md5((salt + password).encode()).hexdigest()
E       TypeError: can only concatenate str (not "PostGenerationMethodCall") to str

env/lib/python3.7/site-packages/django/contrib/auth/hashers.py:508: TypeError

The error stems from

if isinstance(value, factory.declarations.PostGeneration):
.

Changing that check to something like:

        if isinstance(value, factory.declarations.PostGeneration) or isinstance(
                value, factory.declarations.PostGenerationMethodCall
            ):

Seems to fix the issue. I haven't looked at this closely though so not sure if that's the best solution.

possibly relevant versions:
pytest-factoryboy==2.0.3
django==2.2.6
factory-boy==2.12.0
pytest-django==3.6.0

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

Successfully merging a pull request may close this issue.

1 participant