Faker

repository·master·Indexed 12 days ago

https://github.com/joke2k/faker

A Python package for generating realistic fake data for database bootstrapping, XML document creation, stress testing, and data anonymization. It features a proxy class for managing single or multiple locales with weighted selection, unique value generation via the .unique attribute, and various seeding levels (global, instance, and locale).

Tokens
9.2K
Snippets
30
Records
41
Agent score
97%

What's inside Faker

  1. Security constraints for :sample: keyword arguments

    master

    The :sample: generation process uses eval() to parse arguments, which necessitates strict validation to prevent security risks. When providing KWARGS in a :sample: line, they must adhere to the following rules:

    • Allowed Types: Keyword arguments must be literal values or OrderedDict objects.
    • Prohibited Operations: You cannot perform arithmetic (e.g., a=1+1) or call other built-in functions within the :sample: line.
    • Validation Failures: Any attempt to use non-literal values or unauthorized code will cause the validation to fail, and a warning will be logged to the console.

    For implementation details regarding validation, refer to faker.sphinx.validator.SampleCodeValidator and faker.sphinx.docstring.ProviderMethodDocstring in the source code.

  2. How `faker_seed` affects seeding

    master

    The faker fixture guarantees that every test receives a seeded instance, regardless of whether it is session-scoped or function-scoped.

    • If no faker_seed fixture is active, the seed defaults to 0.
    • If a faker_seed fixture is active, its return value is used as the seed.
    • Scope behavior: Like faker_locale, defining a non-session scoped faker_seed fixture will apply that seed to all tests within that scope. You can also use manual injection to pass faker_seed to specific tests.
    import pytest
    
    @pytest.fixture(scope='function')
    def faker_seed():
        return 12345
    
    def test_something(faker):
        # Uses the session seed value
        pass
    
    def test_something_else(faker, faker_seed):
        # Uses the seed value 12345
        pass
  3. Use Faker in Multiple Locale Mode

    master

    You can instantiate a Faker instance with multiple locales by passing a list or an OrderedDict of locales. When calling provider methods directly on the Faker instance (e.g., fake.name()), the library selects a locale based on the weights provided during instantiation.

    To access a specific locale's generator directly, use subscript notation (e.g., fake['en_US']). This allows you to call provider methods that might only be supported by specific locales.

    Key attributes and methods:

    • fake.locales: Returns the list of locales specified during instantiation.
    • fake.factories: Returns the list of internal generators (one per locale).
    • fake['locale_name']: Accesses the internal generator for a specific locale. Raises KeyError if the locale was not included during instantiation.
    • fake.name(): Generates a value using weighted selection across all locales.
    • fake['en_US'].name(): Generates a value specifically using the en_US locale.
    from collections import OrderedDict
    from faker import Faker
    
    # Define locales with weights (higher number = higher probability)
    locales = OrderedDict([
        ('en-US', 1),
        ('en-PH', 2),
        ('ja_JP', 3),
    ])
    fake = Faker(locales)
    
    # Weighted generation
    name = fake.name() 
    
    # Specific locale generation
    name_us = fake['en_US'].name()
  4. Use localized data with Faker

    master

    You can pass a locale string (e.g., 'it_IT') to the Faker constructor to receive data localized to that region. If a localized provider is not found, it falls back to en_US.

    Starting from v3.0.0, Faker also supports passing a list of locales to provide a mix of localized data.

    from faker import Faker
    
    # Single locale
    fake_it = Faker('it_IT')
    print(fake_it.name())
    
    # Multiple locales
    fake_multi = Faker(['it_IT', 'en_US', 'ja_JP'])
    for _ in range(10):
        print(fake_multi.name())
  5. Docstring preprocessing and :examples: generation

    master

    The documentation build process uses sphinx.ext.autodoc to preprocess docstrings. When valid :sample: lines are detected, they are removed from their original position and all generated outputs are collected into a single :examples: section appended to the end of the docstring.

    Important Guidelines

    1. Placement: Because :sample: lines are moved to the end of the docstring during preprocessing, you should place all :sample: lines at the end of your docstring to ensure the logical flow of your text remains intact.
    2. Validation: If a :sample: line is malformed, it will be discarded, and a warning will be logged to the console.
    3. Fallback: If a provider method lacks a docstring or valid :sample: lines, a default sample usage section is automatically generated.
    4. Errors: If a sample run fails (e.g., due to invalid KWARGS or an exception raised by the method), a warning will be logged to the console.
  6. How `faker_locale` affects fixture scoping

    master

    The faker fixture is designed to be session-scoped for performance, but it can be forced to return a new, function-scoped instance for specific tests by activating a faker_locale fixture.

    • Automatic switching: If you define an autouse faker_locale fixture with a non-session scope (e.g., in a submodule's conftest.py), the faker fixture will automatically provide a new instance for all tests in that scope.
    • Manual injection: If you want fine-grained control, define faker_locale without autouse=True and inject it explicitly into the tests that require a specific locale.
    import pytest
    
    # Option 1: Automatic switching for a scope
    @pytest.fixture(scope='function', autouse=True)
    def faker_locale():
        return ['it_IT']
    
    # Option 2: Manual injection for specific tests
    @pytest.fixture()
    def faker_locale():
        return ['it_IT']
    
    def test_something(faker):
        # Uses the session-scoped instance
        pass
    
    def test_something_else(faker, faker_locale):
        # Uses a new, function-scoped instance
        pass
  7. How the new Faker proxy class works

    master

    The modern Faker class is a proxy object that manages one or more Generator objects (the internal engines that produce data).

    • Single Locale Mode: Occurs when you provide one locale (or an empty value, which defaults to en_US). In this mode, the Faker instance proxies calls, properties, and attributes 1:1 to the single internal Generator. It behaves almost identically to the legacy Factory.create shortcut.
    • Multiple Locale Mode: Occurs when you provide multiple locales. In this mode, the Faker instance uses selection logic to decide which internal Generator to use when you call a provider method (e.g., fake.name()).

    Because of the complexity of multiple locale mode, it is recommended to create your own subclass or call methods directly on the internal Generator objects if you need to access attributes like add_provider or the random getter/setter.

    from faker import Faker
    # Single locale mode
    fake = Faker('en_US')
    
    # Multiple locale mode
    fake = Faker(['en_US', 'ja_JP'])
  8. How provider method selection works in Multiple Locale Mode

    master

    When in Multiple Locale Mode, calling a provider method (like fake.name()) follows this selection logic:

    1. Cache Check: If a mapping for this provider method already exists, use it.
    2. Capability Check: If no cache exists, identify which internal Generator objects support the method and cache that mapping (including weights).
    3. Error Handling: If no generator supports the method, raise AttributeError.
    4. Single Match: If only one generator supports the method, return that generator.
    5. Weighted Selection: If multiple generators support it and weights were provided, select a generator based on the provided distribution.
    6. Uniform Selection: If multiple generators support it and no weights were provided, select one using random.choice (uniform distribution).
  9. Install Faker via pip

    master

    Install the Faker package using pip to start generating fake data in your Python projects.

    pip install Faker
  10. Upgrade to the new Faker class (Legacy Compatibility)

    master

    If you want to transition to the new Faker proxy class while maintaining the ability to use legacy behavior (like instance-level .seed() calls), you can manually redefine Faker as the old Factory.create shortcut.

    Note: This conservative approach prevents you from using multiple locale support and the ability to subclass Faker, but it ensures your existing code remains unaffected by the new proxy implementation.

    from faker.factory import Factory
    Faker = Factory.create
    fake = Faker()
    fake.seed(0)  # This will now work as before
  11. Seed the Faker generator for deterministic data

    master

    To ensure that Faker generates the same dataset every time (useful for unit testing), you can seed the random number generator.

    There are two ways to seed:

    1. Global Seeding: Use Faker.seed(value) to seed the shared random number generator used by all instances.
    2. Instance Seeding: Use fake.seed_instance(value) on a specific Faker instance to use a private random.Random instance, separating it from the shared one.

    Warning: Because datasets are updated regularly, results are not guaranteed to be consistent across different patch versions. If you hardcode expected results in your tests, you must pin your Faker version to a specific patch number.

    from faker import Faker
    
    # Global seeding
    fake = Faker()
    Faker.seed(4321)
    print(fake.name())
    # 'Margaret Boehm'
    
    # Instance-specific seeding
    fake = Faker()
    fake.seed_instance(4321)
    print(fake.name())
    # 'Margaret Boehm'
  12. Basic Usage of Faker

    master

    To use Faker, initialize a faker.Faker() generator. You can then access various data types (like names, addresses, or text) by calling methods on the generator instance. Each call yields a different random result.

    from faker import Faker
    fake = Faker()
    
    print(fake.name())
    print(fake.address())
    print(fake.text())