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

Share faker generator with Factory Boy's faker registry #554

Open
chriswyatt opened this issue Jan 10, 2019 · 5 comments
Open

Share faker generator with Factory Boy's faker registry #554

chriswyatt opened this issue Jan 10, 2019 · 5 comments

Comments

@chriswyatt
Copy link

chriswyatt commented Jan 10, 2019

The problem

No documented way to share an existing faker generator with Factory Boy. Sometimes you might not always want to use the faker library from Factory Boy's Faker class, so it would be nice if Factory Boy could share a common faker generator.

Proposed solution

Allow an easy way to attach an existing faker generator to Factory Boy. Perhaps something like factory.Faker.attach_fake(faker_generator), assuming that's possible?

Workaround

import factory
from faker import Factory as FakerFactory

LOCALE = 'en-US'
fake = FakerFactory.create(locale=LOCALE)
factory.Faker._DEFAULT_LOCALE = LOCALE
factory.Faker._FAKER_REGISTRY[LOCALE] = fake

Extra notes

@rbarrois
Copy link
Member

That's indeed a limitation. Do you have some examples of things you run on those custom fakers?
This would help designing a relevant API :)

@chriswyatt
Copy link
Author

chriswyatt commented Feb 20, 2019

The only thing special about the faker in my projects, is setting the locale, adding custom providers, and also setting the faker seed. Nothing particularly special with my use case.

It was mainly being able to use the custom providers, as I could have lived with the locale being wrong, and the seed not being the same.

Here's an example of a couple of providers I wrote. The rest I can't share, as they're more sensitive (these aren't open source projects):

from faker.providers.date_time import Provider as DateTimeProvider
from faker.providers.python import Provider as PythonProvider
from faker.providers.misc import Provider as MiscProvider

class Rfc3339Provider(DateTimeProvider):

    def rfc_3339(self, utc=False):
        """
        Returns a RFC 3339 string
        """
        tz = pytz.timezone(random.choice(pytz.all_timezones))
        return generate(self.date_time(tzinfo=tz), utc=utc)


class ExtraProvider(PythonProvider, MiscProvider):

    def float_32(self, positive=None):
        fraction = self.generator.random.randrange(0, 1 << 23)
        exponent = self.generator.random.randrange(1, 255)

        if positive is None:
            positive_ = self.boolean()
        else:
            assert positive in (False, True)
            positive_ = positive

        bin_32 = fraction | (exponent << 23) | ((not positive_) << 31)

        (float_32, ) = unpack('>f', pack('>I', bin_32))
        return float_32


fake.add_provider(Rfc3339Provider)
fake.add_provider(ExtraProvider)

The seed stuff is useful for having a chance of replicating inconsistent test failures, as you can feed in the same seed, and hopefully the tests will fail in the same way. Personally I haven't needed to do this (yet), but it's something that could be useful:

seed = random.seed()
# ... store seed in DB
fake.seed(seed)

@x-yuri
Copy link

x-yuri commented Jan 4, 2021

I believe resolving #407 resolves this issue as well. Since this one was created in hope to work around the former. As it is you can add custom providers:

import factory, faker

class MyProvider(faker.providers.BaseProvider):
    def smth(self):
        return self.random_element([1, 2, 3])

factory.Faker.add_provider(MyProvider)

And set the seed. Although I believe it's poorly documented. And I'm going to file a corresponding issue. I can mention there anybody interested.

@x-yuri
Copy link

x-yuri commented Jan 10, 2021

The only thing special about the faker in my projects, is setting the locale, adding custom providers, and also setting the faker seed.

Setting the locale:
#407 (comment)
#832

Adding providers: see the previous post.

Setting the seed:
#833

@chriswyatt
Copy link
Author

chriswyatt commented Jan 11, 2021

Thank you. This is very useful. Seeing as the other tickets, cover it, I guess this can be closed then?

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

No branches or pull requests

3 participants